xref: /aosp_15_r20/frameworks/av/media/libmedia/MediaProfiles.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker **
3*ec779b8eSAndroid Build Coastguard Worker ** Copyright 2010, The Android Open Source Project
4*ec779b8eSAndroid Build Coastguard Worker **
5*ec779b8eSAndroid Build Coastguard Worker ** Licensed under the Apache License, Version 2.0 (the "License");
6*ec779b8eSAndroid Build Coastguard Worker ** you may not use this file except in compliance with the License.
7*ec779b8eSAndroid Build Coastguard Worker ** You may obtain a copy of the License at
8*ec779b8eSAndroid Build Coastguard Worker **
9*ec779b8eSAndroid Build Coastguard Worker **     http://www.apache.org/licenses/LICENSE-2.0
10*ec779b8eSAndroid Build Coastguard Worker **
11*ec779b8eSAndroid Build Coastguard Worker ** Unless required by applicable law or agreed to in writing, software
12*ec779b8eSAndroid Build Coastguard Worker ** distributed under the License is distributed on an "AS IS" BASIS,
13*ec779b8eSAndroid Build Coastguard Worker ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*ec779b8eSAndroid Build Coastguard Worker ** See the License for the specific language governing permissions and
15*ec779b8eSAndroid Build Coastguard Worker ** limitations under the License.
16*ec779b8eSAndroid Build Coastguard Worker */
17*ec779b8eSAndroid Build Coastguard Worker 
18*ec779b8eSAndroid Build Coastguard Worker 
19*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
20*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "MediaProfiles"
21*ec779b8eSAndroid Build Coastguard Worker 
22*ec779b8eSAndroid Build Coastguard Worker #include <stdlib.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <utils/misc.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <utils/Vector.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <cutils/properties.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <expat.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <media/MediaProfiles.h>
29*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ADebug.h>
30*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/MediaCodecConstants.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <OMX_Video.h>
32*ec779b8eSAndroid Build Coastguard Worker #include <sys/stat.h>
33*ec779b8eSAndroid Build Coastguard Worker 
34*ec779b8eSAndroid Build Coastguard Worker #include <array>
35*ec779b8eSAndroid Build Coastguard Worker #include <string>
36*ec779b8eSAndroid Build Coastguard Worker #include <vector>
37*ec779b8eSAndroid Build Coastguard Worker 
38*ec779b8eSAndroid Build Coastguard Worker namespace android {
39*ec779b8eSAndroid Build Coastguard Worker 
40*ec779b8eSAndroid Build Coastguard Worker namespace /* unnamed */ {
41*ec779b8eSAndroid Build Coastguard Worker 
42*ec779b8eSAndroid Build Coastguard Worker // Returns a list of possible paths for the media_profiles XML file.
getXmlPaths()43*ec779b8eSAndroid Build Coastguard Worker std::array<char const*, 5> const& getXmlPaths() {
44*ec779b8eSAndroid Build Coastguard Worker     static std::array<std::string const, 5> const paths =
45*ec779b8eSAndroid Build Coastguard Worker         []() -> decltype(paths) {
46*ec779b8eSAndroid Build Coastguard Worker             // Directories for XML file that will be searched (in this order).
47*ec779b8eSAndroid Build Coastguard Worker             constexpr std::array<char const*, 4> searchDirs = {
48*ec779b8eSAndroid Build Coastguard Worker                 "product/etc/",
49*ec779b8eSAndroid Build Coastguard Worker                 "odm/etc/",
50*ec779b8eSAndroid Build Coastguard Worker                 "vendor/etc/",
51*ec779b8eSAndroid Build Coastguard Worker                 "system/etc/",
52*ec779b8eSAndroid Build Coastguard Worker             };
53*ec779b8eSAndroid Build Coastguard Worker 
54*ec779b8eSAndroid Build Coastguard Worker             // The file name may contain a variant if the vendor property
55*ec779b8eSAndroid Build Coastguard Worker             // ro.vendor.media_profiles_xml_variant is set.
56*ec779b8eSAndroid Build Coastguard Worker             char variant[PROPERTY_VALUE_MAX];
57*ec779b8eSAndroid Build Coastguard Worker             property_get("ro.media.xml_variant.profiles",
58*ec779b8eSAndroid Build Coastguard Worker                          variant,
59*ec779b8eSAndroid Build Coastguard Worker                          "_V1_0");
60*ec779b8eSAndroid Build Coastguard Worker 
61*ec779b8eSAndroid Build Coastguard Worker             std::string fileName =
62*ec779b8eSAndroid Build Coastguard Worker                 std::string("media_profiles") + variant + ".xml";
63*ec779b8eSAndroid Build Coastguard Worker 
64*ec779b8eSAndroid Build Coastguard Worker             return { searchDirs[0] + fileName,
65*ec779b8eSAndroid Build Coastguard Worker                      searchDirs[1] + fileName,
66*ec779b8eSAndroid Build Coastguard Worker                      searchDirs[2] + fileName,
67*ec779b8eSAndroid Build Coastguard Worker                      searchDirs[3] + fileName,
68*ec779b8eSAndroid Build Coastguard Worker                      "system/etc/media_profiles.xml" // System fallback
69*ec779b8eSAndroid Build Coastguard Worker                    };
70*ec779b8eSAndroid Build Coastguard Worker         }();
71*ec779b8eSAndroid Build Coastguard Worker     static std::array<char const*, 5> const cPaths = {
72*ec779b8eSAndroid Build Coastguard Worker             paths[0].data(),
73*ec779b8eSAndroid Build Coastguard Worker             paths[1].data(),
74*ec779b8eSAndroid Build Coastguard Worker             paths[2].data(),
75*ec779b8eSAndroid Build Coastguard Worker             paths[3].data(),
76*ec779b8eSAndroid Build Coastguard Worker             paths[4].data()
77*ec779b8eSAndroid Build Coastguard Worker         };
78*ec779b8eSAndroid Build Coastguard Worker     return cPaths;
79*ec779b8eSAndroid Build Coastguard Worker }
80*ec779b8eSAndroid Build Coastguard Worker 
81*ec779b8eSAndroid Build Coastguard Worker } // unnamed namespace
82*ec779b8eSAndroid Build Coastguard Worker 
83*ec779b8eSAndroid Build Coastguard Worker Mutex MediaProfiles::sLock;
84*ec779b8eSAndroid Build Coastguard Worker bool MediaProfiles::sIsInitialized = false;
85*ec779b8eSAndroid Build Coastguard Worker MediaProfiles *MediaProfiles::sInstance = NULL;
86*ec779b8eSAndroid Build Coastguard Worker 
87*ec779b8eSAndroid Build Coastguard Worker const MediaProfiles::NameToTagMap MediaProfiles::sVideoEncoderNameMap[] = {
88*ec779b8eSAndroid Build Coastguard Worker     {"h263", VIDEO_ENCODER_H263},
89*ec779b8eSAndroid Build Coastguard Worker     {"h264", VIDEO_ENCODER_H264},
90*ec779b8eSAndroid Build Coastguard Worker     {"m4v",  VIDEO_ENCODER_MPEG_4_SP},
91*ec779b8eSAndroid Build Coastguard Worker     {"vp8",  VIDEO_ENCODER_VP8},
92*ec779b8eSAndroid Build Coastguard Worker     {"hevc", VIDEO_ENCODER_HEVC},
93*ec779b8eSAndroid Build Coastguard Worker     {"vp9",  VIDEO_ENCODER_VP9},
94*ec779b8eSAndroid Build Coastguard Worker     {"dolbyvision", VIDEO_ENCODER_DOLBY_VISION},
95*ec779b8eSAndroid Build Coastguard Worker };
96*ec779b8eSAndroid Build Coastguard Worker 
97*ec779b8eSAndroid Build Coastguard Worker const MediaProfiles::NameToTagMap MediaProfiles::sChromaSubsamplingNameMap[] = {
98*ec779b8eSAndroid Build Coastguard Worker     {"yuv 4:2:0", CHROMA_SUBSAMPLING_YUV_420},
99*ec779b8eSAndroid Build Coastguard Worker     {"yuv 4:2:2", CHROMA_SUBSAMPLING_YUV_422},
100*ec779b8eSAndroid Build Coastguard Worker     {"yuv 4:4:4", CHROMA_SUBSAMPLING_YUV_444},
101*ec779b8eSAndroid Build Coastguard Worker };
102*ec779b8eSAndroid Build Coastguard Worker 
103*ec779b8eSAndroid Build Coastguard Worker const MediaProfiles::NameToTagMap MediaProfiles::sHdrFormatNameMap[] = {
104*ec779b8eSAndroid Build Coastguard Worker     {"sdr", HDR_FORMAT_NONE},
105*ec779b8eSAndroid Build Coastguard Worker     {"hlg", HDR_FORMAT_HLG},
106*ec779b8eSAndroid Build Coastguard Worker     {"hdr10", HDR_FORMAT_HDR10},
107*ec779b8eSAndroid Build Coastguard Worker     {"hdr10+", HDR_FORMAT_HDR10PLUS},
108*ec779b8eSAndroid Build Coastguard Worker     {"dolbyvision", HDR_FORMAT_DOLBY_VISION},
109*ec779b8eSAndroid Build Coastguard Worker };
110*ec779b8eSAndroid Build Coastguard Worker 
111*ec779b8eSAndroid Build Coastguard Worker const MediaProfiles::NameToTagMap MediaProfiles::sAudioEncoderNameMap[] = {
112*ec779b8eSAndroid Build Coastguard Worker     {"amrnb",  AUDIO_ENCODER_AMR_NB},
113*ec779b8eSAndroid Build Coastguard Worker     {"amrwb",  AUDIO_ENCODER_AMR_WB},
114*ec779b8eSAndroid Build Coastguard Worker     {"aac",    AUDIO_ENCODER_AAC},
115*ec779b8eSAndroid Build Coastguard Worker     {"heaac",  AUDIO_ENCODER_HE_AAC},
116*ec779b8eSAndroid Build Coastguard Worker     {"aaceld", AUDIO_ENCODER_AAC_ELD},
117*ec779b8eSAndroid Build Coastguard Worker     {"opus",   AUDIO_ENCODER_OPUS}
118*ec779b8eSAndroid Build Coastguard Worker };
119*ec779b8eSAndroid Build Coastguard Worker 
120*ec779b8eSAndroid Build Coastguard Worker const MediaProfiles::NameToTagMap MediaProfiles::sFileFormatMap[] = {
121*ec779b8eSAndroid Build Coastguard Worker     {"3gp", OUTPUT_FORMAT_THREE_GPP},
122*ec779b8eSAndroid Build Coastguard Worker     {"mp4", OUTPUT_FORMAT_MPEG_4}
123*ec779b8eSAndroid Build Coastguard Worker };
124*ec779b8eSAndroid Build Coastguard Worker 
125*ec779b8eSAndroid Build Coastguard Worker const MediaProfiles::NameToTagMap MediaProfiles::sVideoDecoderNameMap[] = {
126*ec779b8eSAndroid Build Coastguard Worker     {"wmv", VIDEO_DECODER_WMV}
127*ec779b8eSAndroid Build Coastguard Worker };
128*ec779b8eSAndroid Build Coastguard Worker 
129*ec779b8eSAndroid Build Coastguard Worker const MediaProfiles::NameToTagMap MediaProfiles::sAudioDecoderNameMap[] = {
130*ec779b8eSAndroid Build Coastguard Worker     {"wma", AUDIO_DECODER_WMA}
131*ec779b8eSAndroid Build Coastguard Worker };
132*ec779b8eSAndroid Build Coastguard Worker 
133*ec779b8eSAndroid Build Coastguard Worker const MediaProfiles::NameToTagMap MediaProfiles::sCamcorderQualityNameMap[] = {
134*ec779b8eSAndroid Build Coastguard Worker     {"low", CAMCORDER_QUALITY_LOW},
135*ec779b8eSAndroid Build Coastguard Worker     {"high", CAMCORDER_QUALITY_HIGH},
136*ec779b8eSAndroid Build Coastguard Worker     {"qcif", CAMCORDER_QUALITY_QCIF},
137*ec779b8eSAndroid Build Coastguard Worker     {"cif", CAMCORDER_QUALITY_CIF},
138*ec779b8eSAndroid Build Coastguard Worker     {"480p", CAMCORDER_QUALITY_480P},
139*ec779b8eSAndroid Build Coastguard Worker     {"720p", CAMCORDER_QUALITY_720P},
140*ec779b8eSAndroid Build Coastguard Worker     {"1080p", CAMCORDER_QUALITY_1080P},
141*ec779b8eSAndroid Build Coastguard Worker     {"2160p", CAMCORDER_QUALITY_2160P},
142*ec779b8eSAndroid Build Coastguard Worker     {"qvga", CAMCORDER_QUALITY_QVGA},
143*ec779b8eSAndroid Build Coastguard Worker     {"vga", CAMCORDER_QUALITY_VGA},
144*ec779b8eSAndroid Build Coastguard Worker     {"4kdci", CAMCORDER_QUALITY_4KDCI},
145*ec779b8eSAndroid Build Coastguard Worker     {"qhd", CAMCORDER_QUALITY_QHD},
146*ec779b8eSAndroid Build Coastguard Worker     {"2k", CAMCORDER_QUALITY_2K},
147*ec779b8eSAndroid Build Coastguard Worker     {"8kuhd", CAMCORDER_QUALITY_8KUHD},
148*ec779b8eSAndroid Build Coastguard Worker 
149*ec779b8eSAndroid Build Coastguard Worker     {"timelapselow",  CAMCORDER_QUALITY_TIME_LAPSE_LOW},
150*ec779b8eSAndroid Build Coastguard Worker     {"timelapsehigh", CAMCORDER_QUALITY_TIME_LAPSE_HIGH},
151*ec779b8eSAndroid Build Coastguard Worker     {"timelapseqcif", CAMCORDER_QUALITY_TIME_LAPSE_QCIF},
152*ec779b8eSAndroid Build Coastguard Worker     {"timelapsecif", CAMCORDER_QUALITY_TIME_LAPSE_CIF},
153*ec779b8eSAndroid Build Coastguard Worker     {"timelapse480p", CAMCORDER_QUALITY_TIME_LAPSE_480P},
154*ec779b8eSAndroid Build Coastguard Worker     {"timelapse720p", CAMCORDER_QUALITY_TIME_LAPSE_720P},
155*ec779b8eSAndroid Build Coastguard Worker     {"timelapse1080p", CAMCORDER_QUALITY_TIME_LAPSE_1080P},
156*ec779b8eSAndroid Build Coastguard Worker     {"timelapse2160p", CAMCORDER_QUALITY_TIME_LAPSE_2160P},
157*ec779b8eSAndroid Build Coastguard Worker     {"timelapseqvga", CAMCORDER_QUALITY_TIME_LAPSE_QVGA},
158*ec779b8eSAndroid Build Coastguard Worker     {"timelapsevga", CAMCORDER_QUALITY_TIME_LAPSE_VGA},
159*ec779b8eSAndroid Build Coastguard Worker     {"timelapse4kdci", CAMCORDER_QUALITY_TIME_LAPSE_4KDCI},
160*ec779b8eSAndroid Build Coastguard Worker     {"timelapseqhd", CAMCORDER_QUALITY_TIME_LAPSE_QHD},
161*ec779b8eSAndroid Build Coastguard Worker     {"timelapse2k", CAMCORDER_QUALITY_TIME_LAPSE_2K},
162*ec779b8eSAndroid Build Coastguard Worker 
163*ec779b8eSAndroid Build Coastguard Worker     {"highspeedlow",  CAMCORDER_QUALITY_HIGH_SPEED_LOW},
164*ec779b8eSAndroid Build Coastguard Worker     {"highspeedhigh", CAMCORDER_QUALITY_HIGH_SPEED_HIGH},
165*ec779b8eSAndroid Build Coastguard Worker     {"highspeed480p", CAMCORDER_QUALITY_HIGH_SPEED_480P},
166*ec779b8eSAndroid Build Coastguard Worker     {"highspeed720p", CAMCORDER_QUALITY_HIGH_SPEED_720P},
167*ec779b8eSAndroid Build Coastguard Worker     {"highspeed1080p", CAMCORDER_QUALITY_HIGH_SPEED_1080P},
168*ec779b8eSAndroid Build Coastguard Worker     {"highspeed2160p", CAMCORDER_QUALITY_HIGH_SPEED_2160P},
169*ec779b8eSAndroid Build Coastguard Worker     {"highspeedcif", CAMCORDER_QUALITY_HIGH_SPEED_CIF},
170*ec779b8eSAndroid Build Coastguard Worker     {"highspeedvga", CAMCORDER_QUALITY_HIGH_SPEED_VGA},
171*ec779b8eSAndroid Build Coastguard Worker     {"highspeed4kdci", CAMCORDER_QUALITY_HIGH_SPEED_4KDCI},
172*ec779b8eSAndroid Build Coastguard Worker 
173*ec779b8eSAndroid Build Coastguard Worker     // Vendor-specific profiles
174*ec779b8eSAndroid Build Coastguard Worker };
175*ec779b8eSAndroid Build Coastguard Worker 
176*ec779b8eSAndroid Build Coastguard Worker #if LOG_NDEBUG
177*ec779b8eSAndroid Build Coastguard Worker #define UNUSED __unused
178*ec779b8eSAndroid Build Coastguard Worker #else
179*ec779b8eSAndroid Build Coastguard Worker #define UNUSED
180*ec779b8eSAndroid Build Coastguard Worker #endif
181*ec779b8eSAndroid Build Coastguard Worker 
182*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
logVideoCodec(const MediaProfiles::VideoCodec & codec UNUSED)183*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::logVideoCodec(const MediaProfiles::VideoCodec& codec UNUSED)
184*ec779b8eSAndroid Build Coastguard Worker {
185*ec779b8eSAndroid Build Coastguard Worker     ALOGV("video codec:");
186*ec779b8eSAndroid Build Coastguard Worker     ALOGV("codec = %d (%s)", codec.mCodec,
187*ec779b8eSAndroid Build Coastguard Worker             findNameForTag(sVideoEncoderNameMap, NELEM(sVideoEncoderNameMap), codec.mCodec));
188*ec779b8eSAndroid Build Coastguard Worker     ALOGV("bit rate: %d", codec.mBitRate);
189*ec779b8eSAndroid Build Coastguard Worker     ALOGV("frame width: %d", codec.mFrameWidth);
190*ec779b8eSAndroid Build Coastguard Worker     ALOGV("frame height: %d", codec.mFrameHeight);
191*ec779b8eSAndroid Build Coastguard Worker     ALOGV("frame rate: %d", codec.mFrameRate);
192*ec779b8eSAndroid Build Coastguard Worker     ALOGV("profile: %d", codec.mProfile);
193*ec779b8eSAndroid Build Coastguard Worker     ALOGV("chroma: %s", findNameForTag(sChromaSubsamplingNameMap, NELEM(sChromaSubsamplingNameMap),
194*ec779b8eSAndroid Build Coastguard Worker                                        codec.mChromaSubsampling));
195*ec779b8eSAndroid Build Coastguard Worker     ALOGV("bit depth: %d", codec.mBitDepth);
196*ec779b8eSAndroid Build Coastguard Worker     ALOGV("hdr format: %s", findNameForTag(sHdrFormatNameMap, NELEM(sHdrFormatNameMap),
197*ec779b8eSAndroid Build Coastguard Worker                                            codec.mHdrFormat));
198*ec779b8eSAndroid Build Coastguard Worker }
199*ec779b8eSAndroid Build Coastguard Worker 
200*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
logAudioCodec(const MediaProfiles::AudioCodec & codec UNUSED)201*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::logAudioCodec(const MediaProfiles::AudioCodec& codec UNUSED)
202*ec779b8eSAndroid Build Coastguard Worker {
203*ec779b8eSAndroid Build Coastguard Worker     ALOGV("audio codec:");
204*ec779b8eSAndroid Build Coastguard Worker     ALOGV("codec = %d", codec.mCodec);
205*ec779b8eSAndroid Build Coastguard Worker     ALOGV("bit rate: %d", codec.mBitRate);
206*ec779b8eSAndroid Build Coastguard Worker     ALOGV("sample rate: %d", codec.mSampleRate);
207*ec779b8eSAndroid Build Coastguard Worker     ALOGV("number of channels: %d", codec.mChannels);
208*ec779b8eSAndroid Build Coastguard Worker     ALOGV("profile: %d", codec.mProfile);
209*ec779b8eSAndroid Build Coastguard Worker }
210*ec779b8eSAndroid Build Coastguard Worker 
211*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
logVideoEncoderCap(const MediaProfiles::VideoEncoderCap & cap UNUSED)212*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::logVideoEncoderCap(const MediaProfiles::VideoEncoderCap& cap UNUSED)
213*ec779b8eSAndroid Build Coastguard Worker {
214*ec779b8eSAndroid Build Coastguard Worker     ALOGV("video encoder cap:");
215*ec779b8eSAndroid Build Coastguard Worker     ALOGV("codec = %d", cap.mCodec);
216*ec779b8eSAndroid Build Coastguard Worker     ALOGV("bit rate: min = %d and max = %d", cap.mMinBitRate, cap.mMaxBitRate);
217*ec779b8eSAndroid Build Coastguard Worker     ALOGV("frame width: min = %d and max = %d", cap.mMinFrameWidth, cap.mMaxFrameWidth);
218*ec779b8eSAndroid Build Coastguard Worker     ALOGV("frame height: min = %d and max = %d", cap.mMinFrameHeight, cap.mMaxFrameHeight);
219*ec779b8eSAndroid Build Coastguard Worker     ALOGV("frame rate: min = %d and max = %d", cap.mMinFrameRate, cap.mMaxFrameRate);
220*ec779b8eSAndroid Build Coastguard Worker }
221*ec779b8eSAndroid Build Coastguard Worker 
222*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
logAudioEncoderCap(const MediaProfiles::AudioEncoderCap & cap UNUSED)223*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::logAudioEncoderCap(const MediaProfiles::AudioEncoderCap& cap UNUSED)
224*ec779b8eSAndroid Build Coastguard Worker {
225*ec779b8eSAndroid Build Coastguard Worker     ALOGV("audio encoder cap:");
226*ec779b8eSAndroid Build Coastguard Worker     ALOGV("codec = %d", cap.mCodec);
227*ec779b8eSAndroid Build Coastguard Worker     ALOGV("bit rate: min = %d and max = %d", cap.mMinBitRate, cap.mMaxBitRate);
228*ec779b8eSAndroid Build Coastguard Worker     ALOGV("sample rate: min = %d and max = %d", cap.mMinSampleRate, cap.mMaxSampleRate);
229*ec779b8eSAndroid Build Coastguard Worker     ALOGV("number of channels: min = %d and max = %d", cap.mMinChannels, cap.mMaxChannels);
230*ec779b8eSAndroid Build Coastguard Worker }
231*ec779b8eSAndroid Build Coastguard Worker 
232*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
logVideoDecoderCap(const MediaProfiles::VideoDecoderCap & cap UNUSED)233*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::logVideoDecoderCap(const MediaProfiles::VideoDecoderCap& cap UNUSED)
234*ec779b8eSAndroid Build Coastguard Worker {
235*ec779b8eSAndroid Build Coastguard Worker     ALOGV("video decoder cap:");
236*ec779b8eSAndroid Build Coastguard Worker     ALOGV("codec = %d", cap.mCodec);
237*ec779b8eSAndroid Build Coastguard Worker }
238*ec779b8eSAndroid Build Coastguard Worker 
239*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
logAudioDecoderCap(const MediaProfiles::AudioDecoderCap & cap UNUSED)240*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::logAudioDecoderCap(const MediaProfiles::AudioDecoderCap& cap UNUSED)
241*ec779b8eSAndroid Build Coastguard Worker {
242*ec779b8eSAndroid Build Coastguard Worker     ALOGV("audio codec cap:");
243*ec779b8eSAndroid Build Coastguard Worker     ALOGV("codec = %d", cap.mCodec);
244*ec779b8eSAndroid Build Coastguard Worker }
245*ec779b8eSAndroid Build Coastguard Worker 
246*ec779b8eSAndroid Build Coastguard Worker /*static*/ int
findTagForName(const MediaProfiles::NameToTagMap * map,size_t nMappings,const char * name)247*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::findTagForName(const MediaProfiles::NameToTagMap *map, size_t nMappings,
248*ec779b8eSAndroid Build Coastguard Worker         const char *name)
249*ec779b8eSAndroid Build Coastguard Worker {
250*ec779b8eSAndroid Build Coastguard Worker     int tag = -1;
251*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < nMappings; ++i) {
252*ec779b8eSAndroid Build Coastguard Worker         if (!strcmp(map[i].name, name)) {
253*ec779b8eSAndroid Build Coastguard Worker             tag = map[i].tag;
254*ec779b8eSAndroid Build Coastguard Worker             break;
255*ec779b8eSAndroid Build Coastguard Worker         }
256*ec779b8eSAndroid Build Coastguard Worker     }
257*ec779b8eSAndroid Build Coastguard Worker     return tag;
258*ec779b8eSAndroid Build Coastguard Worker }
259*ec779b8eSAndroid Build Coastguard Worker 
260*ec779b8eSAndroid Build Coastguard Worker /*static*/ const char *
findNameForTag(const MediaProfiles::NameToTagMap * map,size_t nMappings,int tag,const char * def_)261*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::findNameForTag(
262*ec779b8eSAndroid Build Coastguard Worker         const MediaProfiles::NameToTagMap *map, size_t nMappings, int tag, const char *def_)
263*ec779b8eSAndroid Build Coastguard Worker {
264*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < nMappings; ++i) {
265*ec779b8eSAndroid Build Coastguard Worker         if (map[i].tag == tag) {
266*ec779b8eSAndroid Build Coastguard Worker             return map[i].name;
267*ec779b8eSAndroid Build Coastguard Worker         }
268*ec779b8eSAndroid Build Coastguard Worker     }
269*ec779b8eSAndroid Build Coastguard Worker     return def_;
270*ec779b8eSAndroid Build Coastguard Worker }
271*ec779b8eSAndroid Build Coastguard Worker 
272*ec779b8eSAndroid Build Coastguard Worker /*static*/ bool
detectAdvancedVideoProfile(video_encoder codec,int profile,chroma_subsampling * chroma,int * bitDepth,hdr_format * hdr)273*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::detectAdvancedVideoProfile(
274*ec779b8eSAndroid Build Coastguard Worker         video_encoder codec, int profile,
275*ec779b8eSAndroid Build Coastguard Worker         chroma_subsampling *chroma, int *bitDepth, hdr_format *hdr)
276*ec779b8eSAndroid Build Coastguard Worker {
277*ec779b8eSAndroid Build Coastguard Worker     // default values
278*ec779b8eSAndroid Build Coastguard Worker     *chroma = CHROMA_SUBSAMPLING_YUV_420;
279*ec779b8eSAndroid Build Coastguard Worker     *bitDepth = 8;
280*ec779b8eSAndroid Build Coastguard Worker     *hdr = HDR_FORMAT_NONE;
281*ec779b8eSAndroid Build Coastguard Worker 
282*ec779b8eSAndroid Build Coastguard Worker     switch (codec) {
283*ec779b8eSAndroid Build Coastguard Worker     case VIDEO_ENCODER_H263:
284*ec779b8eSAndroid Build Coastguard Worker     case VIDEO_ENCODER_MPEG_4_SP:
285*ec779b8eSAndroid Build Coastguard Worker     case VIDEO_ENCODER_VP8:
286*ec779b8eSAndroid Build Coastguard Worker         // these are always 4:2:0 SDR 8-bit
287*ec779b8eSAndroid Build Coastguard Worker         return true;
288*ec779b8eSAndroid Build Coastguard Worker 
289*ec779b8eSAndroid Build Coastguard Worker     case VIDEO_ENCODER_H264:
290*ec779b8eSAndroid Build Coastguard Worker         switch (profile) {
291*ec779b8eSAndroid Build Coastguard Worker         case AVCProfileBaseline:
292*ec779b8eSAndroid Build Coastguard Worker         case AVCProfileConstrainedBaseline:
293*ec779b8eSAndroid Build Coastguard Worker         case AVCProfileMain:
294*ec779b8eSAndroid Build Coastguard Worker         case AVCProfileExtended:
295*ec779b8eSAndroid Build Coastguard Worker         case AVCProfileHigh:
296*ec779b8eSAndroid Build Coastguard Worker         case AVCProfileConstrainedHigh:
297*ec779b8eSAndroid Build Coastguard Worker             return true;
298*ec779b8eSAndroid Build Coastguard Worker         case AVCProfileHigh10:
299*ec779b8eSAndroid Build Coastguard Worker             // returning false here as this could be an HLG stream
300*ec779b8eSAndroid Build Coastguard Worker             *bitDepth = 10;
301*ec779b8eSAndroid Build Coastguard Worker             return false;
302*ec779b8eSAndroid Build Coastguard Worker         case AVCProfileHigh422:
303*ec779b8eSAndroid Build Coastguard Worker             *chroma = CHROMA_SUBSAMPLING_YUV_422;
304*ec779b8eSAndroid Build Coastguard Worker             // returning false here as bit-depth could be 8 or 10
305*ec779b8eSAndroid Build Coastguard Worker             return false;
306*ec779b8eSAndroid Build Coastguard Worker         case AVCProfileHigh444:
307*ec779b8eSAndroid Build Coastguard Worker             *chroma = CHROMA_SUBSAMPLING_YUV_444;
308*ec779b8eSAndroid Build Coastguard Worker             // returning false here as bit-depth could be 8 or 10
309*ec779b8eSAndroid Build Coastguard Worker             return false;
310*ec779b8eSAndroid Build Coastguard Worker         default:
311*ec779b8eSAndroid Build Coastguard Worker             return false;
312*ec779b8eSAndroid Build Coastguard Worker         }
313*ec779b8eSAndroid Build Coastguard Worker         // flow does not get here
314*ec779b8eSAndroid Build Coastguard Worker 
315*ec779b8eSAndroid Build Coastguard Worker     case VIDEO_ENCODER_HEVC:
316*ec779b8eSAndroid Build Coastguard Worker         switch (profile) {
317*ec779b8eSAndroid Build Coastguard Worker         case HEVCProfileMain:
318*ec779b8eSAndroid Build Coastguard Worker             return true;
319*ec779b8eSAndroid Build Coastguard Worker         case HEVCProfileMain10:
320*ec779b8eSAndroid Build Coastguard Worker             *bitDepth = 10;
321*ec779b8eSAndroid Build Coastguard Worker             // returning false here as this could be an HLG stream
322*ec779b8eSAndroid Build Coastguard Worker             return false;
323*ec779b8eSAndroid Build Coastguard Worker         case HEVCProfileMain10HDR10:
324*ec779b8eSAndroid Build Coastguard Worker             *bitDepth = 10;
325*ec779b8eSAndroid Build Coastguard Worker             *hdr = HDR_FORMAT_HDR10;
326*ec779b8eSAndroid Build Coastguard Worker             return true;
327*ec779b8eSAndroid Build Coastguard Worker         case HEVCProfileMain10HDR10Plus:
328*ec779b8eSAndroid Build Coastguard Worker             *bitDepth = 10;
329*ec779b8eSAndroid Build Coastguard Worker             *hdr = HDR_FORMAT_HDR10PLUS;
330*ec779b8eSAndroid Build Coastguard Worker             return true;
331*ec779b8eSAndroid Build Coastguard Worker         default:
332*ec779b8eSAndroid Build Coastguard Worker             return false;
333*ec779b8eSAndroid Build Coastguard Worker         }
334*ec779b8eSAndroid Build Coastguard Worker         // flow does not get here
335*ec779b8eSAndroid Build Coastguard Worker 
336*ec779b8eSAndroid Build Coastguard Worker     case VIDEO_ENCODER_VP9:
337*ec779b8eSAndroid Build Coastguard Worker         switch (profile) {
338*ec779b8eSAndroid Build Coastguard Worker         case VP9Profile0:
339*ec779b8eSAndroid Build Coastguard Worker             return true;
340*ec779b8eSAndroid Build Coastguard Worker         case VP9Profile2:
341*ec779b8eSAndroid Build Coastguard Worker             // this is always 10-bit on Android */
342*ec779b8eSAndroid Build Coastguard Worker             *bitDepth = 10;
343*ec779b8eSAndroid Build Coastguard Worker             // returning false here as this could be an HLG stream
344*ec779b8eSAndroid Build Coastguard Worker             return false;
345*ec779b8eSAndroid Build Coastguard Worker         case VP9Profile2HDR:
346*ec779b8eSAndroid Build Coastguard Worker             // this is always 10-bit on Android */
347*ec779b8eSAndroid Build Coastguard Worker             *bitDepth = 10;
348*ec779b8eSAndroid Build Coastguard Worker             *hdr = HDR_FORMAT_HDR10;
349*ec779b8eSAndroid Build Coastguard Worker             return true;
350*ec779b8eSAndroid Build Coastguard Worker         case VP9Profile2HDR10Plus:
351*ec779b8eSAndroid Build Coastguard Worker             *bitDepth = 10;
352*ec779b8eSAndroid Build Coastguard Worker             *hdr = HDR_FORMAT_HDR10PLUS;
353*ec779b8eSAndroid Build Coastguard Worker             return true;
354*ec779b8eSAndroid Build Coastguard Worker         default:
355*ec779b8eSAndroid Build Coastguard Worker             return false;
356*ec779b8eSAndroid Build Coastguard Worker         }
357*ec779b8eSAndroid Build Coastguard Worker         // flow does not get here
358*ec779b8eSAndroid Build Coastguard Worker 
359*ec779b8eSAndroid Build Coastguard Worker     case VIDEO_ENCODER_DOLBY_VISION:
360*ec779b8eSAndroid Build Coastguard Worker     {
361*ec779b8eSAndroid Build Coastguard Worker         // for Dolby Vision codec we always assume 10-bit DV
362*ec779b8eSAndroid Build Coastguard Worker         *bitDepth = 10;
363*ec779b8eSAndroid Build Coastguard Worker         *hdr = HDR_FORMAT_DOLBY_VISION;
364*ec779b8eSAndroid Build Coastguard Worker 
365*ec779b8eSAndroid Build Coastguard Worker         switch (profile) {
366*ec779b8eSAndroid Build Coastguard Worker         case DolbyVisionProfileDvheDer /* profile 2 deprecated */:
367*ec779b8eSAndroid Build Coastguard Worker         case DolbyVisionProfileDvheDen /* profile 3 deprecated */:
368*ec779b8eSAndroid Build Coastguard Worker         case DolbyVisionProfileDvavPer /* profile 0 deprecated */:
369*ec779b8eSAndroid Build Coastguard Worker         case DolbyVisionProfileDvavPen /* profile 1 deprecated */:
370*ec779b8eSAndroid Build Coastguard Worker         case DolbyVisionProfileDvheDtr /* dvhe.04 */:
371*ec779b8eSAndroid Build Coastguard Worker         case DolbyVisionProfileDvheStn /* dvhe.05 */:
372*ec779b8eSAndroid Build Coastguard Worker         case DolbyVisionProfileDvheDth /* profile 6 deprecated */:
373*ec779b8eSAndroid Build Coastguard Worker         case DolbyVisionProfileDvheDtb /* dvhe.07 */:
374*ec779b8eSAndroid Build Coastguard Worker         case DolbyVisionProfileDvheSt  /* dvhe.08 */:
375*ec779b8eSAndroid Build Coastguard Worker         case DolbyVisionProfileDvavSe  /* dvav.09 */:
376*ec779b8eSAndroid Build Coastguard Worker         case DolbyVisionProfileDvav110 /* dvav1.10 */:
377*ec779b8eSAndroid Build Coastguard Worker             return true;
378*ec779b8eSAndroid Build Coastguard Worker         default:
379*ec779b8eSAndroid Build Coastguard Worker             return false;
380*ec779b8eSAndroid Build Coastguard Worker         }
381*ec779b8eSAndroid Build Coastguard Worker         // flow does not get here
382*ec779b8eSAndroid Build Coastguard Worker     }
383*ec779b8eSAndroid Build Coastguard Worker 
384*ec779b8eSAndroid Build Coastguard Worker     case VIDEO_ENCODER_AV1:
385*ec779b8eSAndroid Build Coastguard Worker         switch (profile) {
386*ec779b8eSAndroid Build Coastguard Worker         case AV1ProfileMain10:
387*ec779b8eSAndroid Build Coastguard Worker             *bitDepth = 10;
388*ec779b8eSAndroid Build Coastguard Worker             // returning false here as this could be an HLG stream
389*ec779b8eSAndroid Build Coastguard Worker             return false;
390*ec779b8eSAndroid Build Coastguard Worker         case AV1ProfileMain10HDR10:
391*ec779b8eSAndroid Build Coastguard Worker             *bitDepth = 10;
392*ec779b8eSAndroid Build Coastguard Worker             *hdr = HDR_FORMAT_HDR10;
393*ec779b8eSAndroid Build Coastguard Worker             return true;
394*ec779b8eSAndroid Build Coastguard Worker         case AV1ProfileMain10HDR10Plus:
395*ec779b8eSAndroid Build Coastguard Worker             *bitDepth = 10;
396*ec779b8eSAndroid Build Coastguard Worker             *hdr = HDR_FORMAT_HDR10PLUS;
397*ec779b8eSAndroid Build Coastguard Worker             return true;
398*ec779b8eSAndroid Build Coastguard Worker         default:
399*ec779b8eSAndroid Build Coastguard Worker             return false;
400*ec779b8eSAndroid Build Coastguard Worker         }
401*ec779b8eSAndroid Build Coastguard Worker         // flow does not get here
402*ec779b8eSAndroid Build Coastguard Worker 
403*ec779b8eSAndroid Build Coastguard Worker     default:
404*ec779b8eSAndroid Build Coastguard Worker         return false;
405*ec779b8eSAndroid Build Coastguard Worker     }
406*ec779b8eSAndroid Build Coastguard Worker     // flow does not get here
407*ec779b8eSAndroid Build Coastguard Worker }
408*ec779b8eSAndroid Build Coastguard Worker 
409*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
createVideoCodec(const char ** atts,size_t natts,MediaProfiles * profiles)410*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createVideoCodec(const char **atts, size_t natts, MediaProfiles *profiles)
411*ec779b8eSAndroid Build Coastguard Worker {
412*ec779b8eSAndroid Build Coastguard Worker     CHECK(natts >= 10 &&
413*ec779b8eSAndroid Build Coastguard Worker           !strcmp("codec",     atts[0]) &&
414*ec779b8eSAndroid Build Coastguard Worker           !strcmp("bitRate",   atts[2]) &&
415*ec779b8eSAndroid Build Coastguard Worker           !strcmp("width",     atts[4]) &&
416*ec779b8eSAndroid Build Coastguard Worker           !strcmp("height",    atts[6]) &&
417*ec779b8eSAndroid Build Coastguard Worker           !strcmp("frameRate", atts[8]));
418*ec779b8eSAndroid Build Coastguard Worker 
419*ec779b8eSAndroid Build Coastguard Worker     const size_t nMappings = sizeof(sVideoEncoderNameMap)/sizeof(sVideoEncoderNameMap[0]);
420*ec779b8eSAndroid Build Coastguard Worker     const int codec = findTagForName(sVideoEncoderNameMap, nMappings, atts[1]);
421*ec779b8eSAndroid Build Coastguard Worker     if (codec == -1) {
422*ec779b8eSAndroid Build Coastguard Worker         ALOGE("MediaProfiles::createVideoCodec failed to locate codec %s", atts[1]);
423*ec779b8eSAndroid Build Coastguard Worker         return;
424*ec779b8eSAndroid Build Coastguard Worker     }
425*ec779b8eSAndroid Build Coastguard Worker 
426*ec779b8eSAndroid Build Coastguard Worker     int profile = -1;
427*ec779b8eSAndroid Build Coastguard Worker     chroma_subsampling chroma = CHROMA_SUBSAMPLING_YUV_420;
428*ec779b8eSAndroid Build Coastguard Worker     int bitDepth = 8;
429*ec779b8eSAndroid Build Coastguard Worker     hdr_format hdr = HDR_FORMAT_NONE;
430*ec779b8eSAndroid Build Coastguard Worker     if (codec == VIDEO_ENCODER_DOLBY_VISION) {
431*ec779b8eSAndroid Build Coastguard Worker         bitDepth = 10;
432*ec779b8eSAndroid Build Coastguard Worker         hdr = HDR_FORMAT_DOLBY_VISION;
433*ec779b8eSAndroid Build Coastguard Worker     }
434*ec779b8eSAndroid Build Coastguard Worker 
435*ec779b8eSAndroid Build Coastguard Worker     if (natts >= 12 && !strcmp("profile", atts[10])) {
436*ec779b8eSAndroid Build Coastguard Worker         profile = atoi(atts[11]);
437*ec779b8eSAndroid Build Coastguard Worker         if (!detectAdvancedVideoProfile(
438*ec779b8eSAndroid Build Coastguard Worker                 (video_encoder)codec, profile, &chroma, &bitDepth, &hdr)) {
439*ec779b8eSAndroid Build Coastguard Worker             // if not detected read values from the attributes
440*ec779b8eSAndroid Build Coastguard Worker             for (size_t ix = 12; natts >= ix + 2; ix += 2) {
441*ec779b8eSAndroid Build Coastguard Worker                 if (!strcmp("chroma", atts[ix])) {
442*ec779b8eSAndroid Build Coastguard Worker                     int chromaTag = findTagForName(sChromaSubsamplingNameMap,
443*ec779b8eSAndroid Build Coastguard Worker                                          NELEM(sChromaSubsamplingNameMap), atts[ix + 1]);
444*ec779b8eSAndroid Build Coastguard Worker                     if (chromaTag == -1) {
445*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("MediaProfiles::createVideoCodec invalid chroma %s", atts[ix + 1]);
446*ec779b8eSAndroid Build Coastguard Worker                         return;
447*ec779b8eSAndroid Build Coastguard Worker                     } else {
448*ec779b8eSAndroid Build Coastguard Worker                         chroma = (chroma_subsampling)chromaTag;
449*ec779b8eSAndroid Build Coastguard Worker                     }
450*ec779b8eSAndroid Build Coastguard Worker                 } else if (!strcmp("bitDepth", atts[ix])) {
451*ec779b8eSAndroid Build Coastguard Worker                     bitDepth = atoi(atts[ix + 1]);
452*ec779b8eSAndroid Build Coastguard Worker                     if (bitDepth < 8 || bitDepth > 16) {
453*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("MediaProfiles::createVideoCodec invalid bidDepth %s", atts[ix + 1]);
454*ec779b8eSAndroid Build Coastguard Worker                         return;
455*ec779b8eSAndroid Build Coastguard Worker                     }
456*ec779b8eSAndroid Build Coastguard Worker                 } else if (!strcmp("hdr", atts[ix])) {
457*ec779b8eSAndroid Build Coastguard Worker                     int hdrTag = findTagForName(sHdrFormatNameMap,
458*ec779b8eSAndroid Build Coastguard Worker                                                 NELEM(sHdrFormatNameMap), atts[ix + 1]);
459*ec779b8eSAndroid Build Coastguard Worker                     if (hdrTag == -1) {
460*ec779b8eSAndroid Build Coastguard Worker                         ALOGE("MediaProfiles::createVideoCodec invalid hdr %s", atts[ix + 1]);
461*ec779b8eSAndroid Build Coastguard Worker                         return;
462*ec779b8eSAndroid Build Coastguard Worker                     } else {
463*ec779b8eSAndroid Build Coastguard Worker                         hdr = (hdr_format)hdrTag;
464*ec779b8eSAndroid Build Coastguard Worker                     }
465*ec779b8eSAndroid Build Coastguard Worker                 } else {
466*ec779b8eSAndroid Build Coastguard Worker                     // ignoring here. TODO: rewrite this whole file to ignore invalid attrs
467*ec779b8eSAndroid Build Coastguard Worker                     ALOGD("MediaProfiles::createVideoCodec ignoring invalid attr %s", atts[ix]);
468*ec779b8eSAndroid Build Coastguard Worker                 }
469*ec779b8eSAndroid Build Coastguard Worker             }
470*ec779b8eSAndroid Build Coastguard Worker         }
471*ec779b8eSAndroid Build Coastguard Worker     }
472*ec779b8eSAndroid Build Coastguard Worker 
473*ec779b8eSAndroid Build Coastguard Worker     VideoCodec videoCodec{
474*ec779b8eSAndroid Build Coastguard Worker             static_cast<video_encoder>(codec),
475*ec779b8eSAndroid Build Coastguard Worker             atoi(atts[3]) /* bitRate */, atoi(atts[5]) /* width */, atoi(atts[7]) /* height */,
476*ec779b8eSAndroid Build Coastguard Worker             atoi(atts[9]) /* frameRate */, profile, chroma, bitDepth, hdr };
477*ec779b8eSAndroid Build Coastguard Worker     logVideoCodec(videoCodec);
478*ec779b8eSAndroid Build Coastguard Worker 
479*ec779b8eSAndroid Build Coastguard Worker     size_t nCamcorderProfiles;
480*ec779b8eSAndroid Build Coastguard Worker     CHECK((nCamcorderProfiles = profiles->mCamcorderProfiles.size()) >= 1);
481*ec779b8eSAndroid Build Coastguard Worker     profiles->mCamcorderProfiles[nCamcorderProfiles - 1]->mVideoCodecs.emplace_back(videoCodec);
482*ec779b8eSAndroid Build Coastguard Worker }
483*ec779b8eSAndroid Build Coastguard Worker 
484*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
createAudioCodec(const char ** atts,size_t natts,MediaProfiles * profiles)485*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createAudioCodec(const char **atts, size_t natts, MediaProfiles *profiles)
486*ec779b8eSAndroid Build Coastguard Worker {
487*ec779b8eSAndroid Build Coastguard Worker     CHECK(natts >= 8 &&
488*ec779b8eSAndroid Build Coastguard Worker           !strcmp("codec",      atts[0]) &&
489*ec779b8eSAndroid Build Coastguard Worker           !strcmp("bitRate",    atts[2]) &&
490*ec779b8eSAndroid Build Coastguard Worker           !strcmp("sampleRate", atts[4]) &&
491*ec779b8eSAndroid Build Coastguard Worker           !strcmp("channels",   atts[6]));
492*ec779b8eSAndroid Build Coastguard Worker     const size_t nMappings = sizeof(sAudioEncoderNameMap)/sizeof(sAudioEncoderNameMap[0]);
493*ec779b8eSAndroid Build Coastguard Worker     const int codec = findTagForName(sAudioEncoderNameMap, nMappings, atts[1]);
494*ec779b8eSAndroid Build Coastguard Worker     if (codec == -1) {
495*ec779b8eSAndroid Build Coastguard Worker         ALOGE("MediaProfiles::createAudioCodec failed to locate codec %s", atts[1]);
496*ec779b8eSAndroid Build Coastguard Worker         return;
497*ec779b8eSAndroid Build Coastguard Worker     }
498*ec779b8eSAndroid Build Coastguard Worker 
499*ec779b8eSAndroid Build Coastguard Worker     int profile = -1;
500*ec779b8eSAndroid Build Coastguard Worker     if (natts >= 10 && !strcmp("profile", atts[8])) {
501*ec779b8eSAndroid Build Coastguard Worker         profile = atoi(atts[9]);
502*ec779b8eSAndroid Build Coastguard Worker     }
503*ec779b8eSAndroid Build Coastguard Worker 
504*ec779b8eSAndroid Build Coastguard Worker     AudioCodec audioCodec{
505*ec779b8eSAndroid Build Coastguard Worker             static_cast<audio_encoder>(codec),
506*ec779b8eSAndroid Build Coastguard Worker             atoi(atts[3]), atoi(atts[5]), atoi(atts[7]), profile };
507*ec779b8eSAndroid Build Coastguard Worker     logAudioCodec(audioCodec);
508*ec779b8eSAndroid Build Coastguard Worker 
509*ec779b8eSAndroid Build Coastguard Worker     size_t nCamcorderProfiles;
510*ec779b8eSAndroid Build Coastguard Worker     CHECK((nCamcorderProfiles = profiles->mCamcorderProfiles.size()) >= 1);
511*ec779b8eSAndroid Build Coastguard Worker     profiles->mCamcorderProfiles[nCamcorderProfiles - 1]->mAudioCodecs.emplace_back(audioCodec);
512*ec779b8eSAndroid Build Coastguard Worker }
513*ec779b8eSAndroid Build Coastguard Worker 
514*ec779b8eSAndroid Build Coastguard Worker /*static*/ MediaProfiles::AudioDecoderCap*
createAudioDecoderCap(const char ** atts,size_t natts)515*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createAudioDecoderCap(const char **atts, size_t natts)
516*ec779b8eSAndroid Build Coastguard Worker {
517*ec779b8eSAndroid Build Coastguard Worker     CHECK(natts >= 4 &&
518*ec779b8eSAndroid Build Coastguard Worker           !strcmp("name",    atts[0]) &&
519*ec779b8eSAndroid Build Coastguard Worker           !strcmp("enabled", atts[2]));
520*ec779b8eSAndroid Build Coastguard Worker 
521*ec779b8eSAndroid Build Coastguard Worker     const size_t nMappings = sizeof(sAudioDecoderNameMap)/sizeof(sAudioDecoderNameMap[0]);
522*ec779b8eSAndroid Build Coastguard Worker     const int codec = findTagForName(sAudioDecoderNameMap, nMappings, atts[1]);
523*ec779b8eSAndroid Build Coastguard Worker     if (codec == -1) {
524*ec779b8eSAndroid Build Coastguard Worker       ALOGE("MediaProfiles::createAudioDecoderCap failed to locate codec %s", atts[1]);
525*ec779b8eSAndroid Build Coastguard Worker       return nullptr;
526*ec779b8eSAndroid Build Coastguard Worker     }
527*ec779b8eSAndroid Build Coastguard Worker 
528*ec779b8eSAndroid Build Coastguard Worker     MediaProfiles::AudioDecoderCap *cap =
529*ec779b8eSAndroid Build Coastguard Worker         new MediaProfiles::AudioDecoderCap(static_cast<audio_decoder>(codec));
530*ec779b8eSAndroid Build Coastguard Worker     logAudioDecoderCap(*cap);
531*ec779b8eSAndroid Build Coastguard Worker     return cap;
532*ec779b8eSAndroid Build Coastguard Worker }
533*ec779b8eSAndroid Build Coastguard Worker 
534*ec779b8eSAndroid Build Coastguard Worker /*static*/ MediaProfiles::VideoDecoderCap*
createVideoDecoderCap(const char ** atts,size_t natts)535*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createVideoDecoderCap(const char **atts, size_t natts)
536*ec779b8eSAndroid Build Coastguard Worker {
537*ec779b8eSAndroid Build Coastguard Worker     CHECK(natts >= 4 &&
538*ec779b8eSAndroid Build Coastguard Worker           !strcmp("name",    atts[0]) &&
539*ec779b8eSAndroid Build Coastguard Worker           !strcmp("enabled", atts[2]));
540*ec779b8eSAndroid Build Coastguard Worker 
541*ec779b8eSAndroid Build Coastguard Worker     const size_t nMappings = sizeof(sVideoDecoderNameMap)/sizeof(sVideoDecoderNameMap[0]);
542*ec779b8eSAndroid Build Coastguard Worker     const int codec = findTagForName(sVideoDecoderNameMap, nMappings, atts[1]);
543*ec779b8eSAndroid Build Coastguard Worker     if (codec == -1) {
544*ec779b8eSAndroid Build Coastguard Worker       ALOGE("MediaProfiles::createVideoDecoderCap failed to locate codec %s", atts[1]);
545*ec779b8eSAndroid Build Coastguard Worker       return nullptr;
546*ec779b8eSAndroid Build Coastguard Worker     }
547*ec779b8eSAndroid Build Coastguard Worker 
548*ec779b8eSAndroid Build Coastguard Worker     MediaProfiles::VideoDecoderCap *cap =
549*ec779b8eSAndroid Build Coastguard Worker         new MediaProfiles::VideoDecoderCap(static_cast<video_decoder>(codec));
550*ec779b8eSAndroid Build Coastguard Worker     logVideoDecoderCap(*cap);
551*ec779b8eSAndroid Build Coastguard Worker     return cap;
552*ec779b8eSAndroid Build Coastguard Worker }
553*ec779b8eSAndroid Build Coastguard Worker 
554*ec779b8eSAndroid Build Coastguard Worker /*static*/ MediaProfiles::VideoEncoderCap*
createVideoEncoderCap(const char ** atts,size_t natts)555*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createVideoEncoderCap(const char **atts, size_t natts)
556*ec779b8eSAndroid Build Coastguard Worker {
557*ec779b8eSAndroid Build Coastguard Worker     CHECK(natts >= 20 &&
558*ec779b8eSAndroid Build Coastguard Worker           !strcmp("name",           atts[0])  &&
559*ec779b8eSAndroid Build Coastguard Worker           !strcmp("enabled",        atts[2])  &&
560*ec779b8eSAndroid Build Coastguard Worker           !strcmp("minBitRate",     atts[4])  &&
561*ec779b8eSAndroid Build Coastguard Worker           !strcmp("maxBitRate",     atts[6])  &&
562*ec779b8eSAndroid Build Coastguard Worker           !strcmp("minFrameWidth",  atts[8])  &&
563*ec779b8eSAndroid Build Coastguard Worker           !strcmp("maxFrameWidth",  atts[10]) &&
564*ec779b8eSAndroid Build Coastguard Worker           !strcmp("minFrameHeight", atts[12]) &&
565*ec779b8eSAndroid Build Coastguard Worker           !strcmp("maxFrameHeight", atts[14]) &&
566*ec779b8eSAndroid Build Coastguard Worker           !strcmp("minFrameRate",   atts[16]) &&
567*ec779b8eSAndroid Build Coastguard Worker           !strcmp("maxFrameRate",   atts[18]));
568*ec779b8eSAndroid Build Coastguard Worker 
569*ec779b8eSAndroid Build Coastguard Worker     const size_t nMappings = sizeof(sVideoEncoderNameMap)/sizeof(sVideoEncoderNameMap[0]);
570*ec779b8eSAndroid Build Coastguard Worker     const int codec = findTagForName(sVideoEncoderNameMap, nMappings, atts[1]);
571*ec779b8eSAndroid Build Coastguard Worker     if (codec == -1) {
572*ec779b8eSAndroid Build Coastguard Worker       ALOGE("MediaProfiles::createVideoEncoderCap failed to locate codec %s", atts[1]);
573*ec779b8eSAndroid Build Coastguard Worker       return nullptr;
574*ec779b8eSAndroid Build Coastguard Worker     }
575*ec779b8eSAndroid Build Coastguard Worker 
576*ec779b8eSAndroid Build Coastguard Worker     MediaProfiles::VideoEncoderCap *cap =
577*ec779b8eSAndroid Build Coastguard Worker         new MediaProfiles::VideoEncoderCap(static_cast<video_encoder>(codec),
578*ec779b8eSAndroid Build Coastguard Worker             atoi(atts[5]), atoi(atts[7]), atoi(atts[9]), atoi(atts[11]), atoi(atts[13]),
579*ec779b8eSAndroid Build Coastguard Worker             atoi(atts[15]), atoi(atts[17]), atoi(atts[19]));
580*ec779b8eSAndroid Build Coastguard Worker     logVideoEncoderCap(*cap);
581*ec779b8eSAndroid Build Coastguard Worker     return cap;
582*ec779b8eSAndroid Build Coastguard Worker }
583*ec779b8eSAndroid Build Coastguard Worker 
584*ec779b8eSAndroid Build Coastguard Worker /*static*/ MediaProfiles::AudioEncoderCap*
createAudioEncoderCap(const char ** atts,size_t natts)585*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createAudioEncoderCap(const char **atts, size_t natts)
586*ec779b8eSAndroid Build Coastguard Worker {
587*ec779b8eSAndroid Build Coastguard Worker     CHECK(natts >= 16 &&
588*ec779b8eSAndroid Build Coastguard Worker           !strcmp("name",          atts[0])  &&
589*ec779b8eSAndroid Build Coastguard Worker           !strcmp("enabled",       atts[2])  &&
590*ec779b8eSAndroid Build Coastguard Worker           !strcmp("minBitRate",    atts[4])  &&
591*ec779b8eSAndroid Build Coastguard Worker           !strcmp("maxBitRate",    atts[6])  &&
592*ec779b8eSAndroid Build Coastguard Worker           !strcmp("minSampleRate", atts[8])  &&
593*ec779b8eSAndroid Build Coastguard Worker           !strcmp("maxSampleRate", atts[10]) &&
594*ec779b8eSAndroid Build Coastguard Worker           !strcmp("minChannels",   atts[12]) &&
595*ec779b8eSAndroid Build Coastguard Worker           !strcmp("maxChannels",   atts[14]));
596*ec779b8eSAndroid Build Coastguard Worker 
597*ec779b8eSAndroid Build Coastguard Worker     const size_t nMappings = sizeof(sAudioEncoderNameMap)/sizeof(sAudioEncoderNameMap[0]);
598*ec779b8eSAndroid Build Coastguard Worker     const int codec = findTagForName(sAudioEncoderNameMap, nMappings, atts[1]);
599*ec779b8eSAndroid Build Coastguard Worker     if (codec == -1) {
600*ec779b8eSAndroid Build Coastguard Worker       ALOGE("MediaProfiles::createAudioEncoderCap failed to locate codec %s", atts[1]);
601*ec779b8eSAndroid Build Coastguard Worker       return nullptr;
602*ec779b8eSAndroid Build Coastguard Worker     }
603*ec779b8eSAndroid Build Coastguard Worker 
604*ec779b8eSAndroid Build Coastguard Worker     MediaProfiles::AudioEncoderCap *cap =
605*ec779b8eSAndroid Build Coastguard Worker         new MediaProfiles::AudioEncoderCap(static_cast<audio_encoder>(codec), atoi(atts[5]),
606*ec779b8eSAndroid Build Coastguard Worker             atoi(atts[7]), atoi(atts[9]), atoi(atts[11]), atoi(atts[13]), atoi(atts[15]));
607*ec779b8eSAndroid Build Coastguard Worker     logAudioEncoderCap(*cap);
608*ec779b8eSAndroid Build Coastguard Worker     return cap;
609*ec779b8eSAndroid Build Coastguard Worker }
610*ec779b8eSAndroid Build Coastguard Worker 
611*ec779b8eSAndroid Build Coastguard Worker /*static*/ output_format
createEncoderOutputFileFormat(const char ** atts,size_t natts)612*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createEncoderOutputFileFormat(const char **atts, size_t natts)
613*ec779b8eSAndroid Build Coastguard Worker {
614*ec779b8eSAndroid Build Coastguard Worker     CHECK(natts >= 2 &&
615*ec779b8eSAndroid Build Coastguard Worker           !strcmp("name", atts[0]));
616*ec779b8eSAndroid Build Coastguard Worker 
617*ec779b8eSAndroid Build Coastguard Worker     const size_t nMappings =sizeof(sFileFormatMap)/sizeof(sFileFormatMap[0]);
618*ec779b8eSAndroid Build Coastguard Worker     const int format = findTagForName(sFileFormatMap, nMappings, atts[1]);
619*ec779b8eSAndroid Build Coastguard Worker     CHECK(format != -1);
620*ec779b8eSAndroid Build Coastguard Worker 
621*ec779b8eSAndroid Build Coastguard Worker     return static_cast<output_format>(format);
622*ec779b8eSAndroid Build Coastguard Worker }
623*ec779b8eSAndroid Build Coastguard Worker 
isCameraIdFound(int cameraId,const Vector<int> & cameraIds)624*ec779b8eSAndroid Build Coastguard Worker static bool isCameraIdFound(int cameraId, const Vector<int>& cameraIds) {
625*ec779b8eSAndroid Build Coastguard Worker     for (int i = 0, n = cameraIds.size(); i < n; ++i) {
626*ec779b8eSAndroid Build Coastguard Worker         if (cameraId == cameraIds[i]) {
627*ec779b8eSAndroid Build Coastguard Worker             return true;
628*ec779b8eSAndroid Build Coastguard Worker         }
629*ec779b8eSAndroid Build Coastguard Worker     }
630*ec779b8eSAndroid Build Coastguard Worker     return false;
631*ec779b8eSAndroid Build Coastguard Worker }
632*ec779b8eSAndroid Build Coastguard Worker 
633*ec779b8eSAndroid Build Coastguard Worker /*static*/ MediaProfiles::CamcorderProfile*
createCamcorderProfile(int cameraId,const char ** atts,size_t natts,Vector<int> & cameraIds)634*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createCamcorderProfile(
635*ec779b8eSAndroid Build Coastguard Worker         int cameraId, const char **atts, size_t natts, Vector<int>& cameraIds)
636*ec779b8eSAndroid Build Coastguard Worker {
637*ec779b8eSAndroid Build Coastguard Worker     CHECK(natts >= 6 &&
638*ec779b8eSAndroid Build Coastguard Worker           !strcmp("quality",    atts[0]) &&
639*ec779b8eSAndroid Build Coastguard Worker           !strcmp("fileFormat", atts[2]) &&
640*ec779b8eSAndroid Build Coastguard Worker           !strcmp("duration",   atts[4]));
641*ec779b8eSAndroid Build Coastguard Worker 
642*ec779b8eSAndroid Build Coastguard Worker     const size_t nProfileMappings = sizeof(sCamcorderQualityNameMap)/
643*ec779b8eSAndroid Build Coastguard Worker             sizeof(sCamcorderQualityNameMap[0]);
644*ec779b8eSAndroid Build Coastguard Worker     const int quality = findTagForName(sCamcorderQualityNameMap, nProfileMappings, atts[1]);
645*ec779b8eSAndroid Build Coastguard Worker     if (quality == -1) {
646*ec779b8eSAndroid Build Coastguard Worker       ALOGE("MediaProfiles::createCamcorderProfile failed to locate quality %s", atts[1]);
647*ec779b8eSAndroid Build Coastguard Worker       return nullptr;
648*ec779b8eSAndroid Build Coastguard Worker     }
649*ec779b8eSAndroid Build Coastguard Worker 
650*ec779b8eSAndroid Build Coastguard Worker     const size_t nFormatMappings = sizeof(sFileFormatMap)/sizeof(sFileFormatMap[0]);
651*ec779b8eSAndroid Build Coastguard Worker     const int fileFormat = findTagForName(sFileFormatMap, nFormatMappings, atts[3]);
652*ec779b8eSAndroid Build Coastguard Worker     if (fileFormat == -1) {
653*ec779b8eSAndroid Build Coastguard Worker       ALOGE("MediaProfiles::createCamcorderProfile failed to locate file format %s", atts[1]);
654*ec779b8eSAndroid Build Coastguard Worker       return nullptr;
655*ec779b8eSAndroid Build Coastguard Worker     }
656*ec779b8eSAndroid Build Coastguard Worker 
657*ec779b8eSAndroid Build Coastguard Worker     MediaProfiles::CamcorderProfile *profile = new MediaProfiles::CamcorderProfile;
658*ec779b8eSAndroid Build Coastguard Worker     profile->mCameraId = cameraId;
659*ec779b8eSAndroid Build Coastguard Worker     if (!isCameraIdFound(cameraId, cameraIds)) {
660*ec779b8eSAndroid Build Coastguard Worker         cameraIds.add(cameraId);
661*ec779b8eSAndroid Build Coastguard Worker     }
662*ec779b8eSAndroid Build Coastguard Worker     profile->mFileFormat = static_cast<output_format>(fileFormat);
663*ec779b8eSAndroid Build Coastguard Worker     profile->mQuality = static_cast<camcorder_quality>(quality);
664*ec779b8eSAndroid Build Coastguard Worker     profile->mDuration = atoi(atts[5]);
665*ec779b8eSAndroid Build Coastguard Worker     return profile;
666*ec779b8eSAndroid Build Coastguard Worker }
667*ec779b8eSAndroid Build Coastguard Worker 
668*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::ImageEncodingQualityLevels*
findImageEncodingQualityLevels(int cameraId) const669*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::findImageEncodingQualityLevels(int cameraId) const
670*ec779b8eSAndroid Build Coastguard Worker {
671*ec779b8eSAndroid Build Coastguard Worker     int n = mImageEncodingQualityLevels.size();
672*ec779b8eSAndroid Build Coastguard Worker     for (int i = 0; i < n; i++) {
673*ec779b8eSAndroid Build Coastguard Worker         ImageEncodingQualityLevels *levels = mImageEncodingQualityLevels[i];
674*ec779b8eSAndroid Build Coastguard Worker         if (levels->mCameraId == cameraId) {
675*ec779b8eSAndroid Build Coastguard Worker             return levels;
676*ec779b8eSAndroid Build Coastguard Worker         }
677*ec779b8eSAndroid Build Coastguard Worker     }
678*ec779b8eSAndroid Build Coastguard Worker     return NULL;
679*ec779b8eSAndroid Build Coastguard Worker }
680*ec779b8eSAndroid Build Coastguard Worker 
addImageEncodingQualityLevel(int cameraId,const char ** atts,size_t natts)681*ec779b8eSAndroid Build Coastguard Worker void MediaProfiles::addImageEncodingQualityLevel(int cameraId, const char** atts, size_t natts)
682*ec779b8eSAndroid Build Coastguard Worker {
683*ec779b8eSAndroid Build Coastguard Worker     CHECK(natts >= 2 &&
684*ec779b8eSAndroid Build Coastguard Worker           !strcmp("quality", atts[0]));
685*ec779b8eSAndroid Build Coastguard Worker     int quality = atoi(atts[1]);
686*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: cameraId=%d, quality=%d", __func__, cameraId, quality);
687*ec779b8eSAndroid Build Coastguard Worker     ImageEncodingQualityLevels *levels = findImageEncodingQualityLevels(cameraId);
688*ec779b8eSAndroid Build Coastguard Worker 
689*ec779b8eSAndroid Build Coastguard Worker     if (levels == NULL) {
690*ec779b8eSAndroid Build Coastguard Worker         levels = new ImageEncodingQualityLevels();
691*ec779b8eSAndroid Build Coastguard Worker         levels->mCameraId = cameraId;
692*ec779b8eSAndroid Build Coastguard Worker         mImageEncodingQualityLevels.add(levels);
693*ec779b8eSAndroid Build Coastguard Worker     }
694*ec779b8eSAndroid Build Coastguard Worker 
695*ec779b8eSAndroid Build Coastguard Worker     levels->mLevels.add(quality);
696*ec779b8eSAndroid Build Coastguard Worker }
697*ec779b8eSAndroid Build Coastguard Worker 
698*ec779b8eSAndroid Build Coastguard Worker /*static*/ int
getCameraId(const char ** atts,size_t natts)699*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::getCameraId(const char** atts, size_t natts)
700*ec779b8eSAndroid Build Coastguard Worker {
701*ec779b8eSAndroid Build Coastguard Worker     if (!atts[0]) return 0;  // default cameraId = 0
702*ec779b8eSAndroid Build Coastguard Worker     CHECK(natts >= 2 &&
703*ec779b8eSAndroid Build Coastguard Worker           !strcmp("cameraId", atts[0]));
704*ec779b8eSAndroid Build Coastguard Worker     return atoi(atts[1]);
705*ec779b8eSAndroid Build Coastguard Worker }
706*ec779b8eSAndroid Build Coastguard Worker 
addStartTimeOffset(int cameraId,const char ** atts,size_t natts)707*ec779b8eSAndroid Build Coastguard Worker void MediaProfiles::addStartTimeOffset(int cameraId, const char** atts, size_t natts)
708*ec779b8eSAndroid Build Coastguard Worker {
709*ec779b8eSAndroid Build Coastguard Worker     int offsetTimeMs = 1000;
710*ec779b8eSAndroid Build Coastguard Worker     if (natts >= 3 && atts[2]) {
711*ec779b8eSAndroid Build Coastguard Worker         CHECK(natts >= 4 && !strcmp("startOffsetMs", atts[2]));
712*ec779b8eSAndroid Build Coastguard Worker         offsetTimeMs = atoi(atts[3]);
713*ec779b8eSAndroid Build Coastguard Worker     }
714*ec779b8eSAndroid Build Coastguard Worker 
715*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: cameraId=%d, offset=%d ms", __func__, cameraId, offsetTimeMs);
716*ec779b8eSAndroid Build Coastguard Worker     mStartTimeOffsets.replaceValueFor(cameraId, offsetTimeMs);
717*ec779b8eSAndroid Build Coastguard Worker }
718*ec779b8eSAndroid Build Coastguard Worker 
719*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
startElementHandler(void * userData,const char * name,const char ** atts)720*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::startElementHandler(void *userData, const char *name, const char **atts)
721*ec779b8eSAndroid Build Coastguard Worker {
722*ec779b8eSAndroid Build Coastguard Worker     // determine number of attributes
723*ec779b8eSAndroid Build Coastguard Worker     size_t natts = 0;
724*ec779b8eSAndroid Build Coastguard Worker     while (atts[natts]) {
725*ec779b8eSAndroid Build Coastguard Worker         ++natts;
726*ec779b8eSAndroid Build Coastguard Worker     }
727*ec779b8eSAndroid Build Coastguard Worker 
728*ec779b8eSAndroid Build Coastguard Worker     MediaProfiles *profiles = (MediaProfiles *)userData;
729*ec779b8eSAndroid Build Coastguard Worker     if (strcmp("Video", name) == 0) {
730*ec779b8eSAndroid Build Coastguard Worker         createVideoCodec(atts, natts, profiles);
731*ec779b8eSAndroid Build Coastguard Worker     } else if (strcmp("Audio", name) == 0) {
732*ec779b8eSAndroid Build Coastguard Worker         createAudioCodec(atts, natts, profiles);
733*ec779b8eSAndroid Build Coastguard Worker     } else if (strcmp("VideoEncoderCap", name) == 0 &&
734*ec779b8eSAndroid Build Coastguard Worker                natts >= 4 &&
735*ec779b8eSAndroid Build Coastguard Worker                strcmp("true", atts[3]) == 0) {
736*ec779b8eSAndroid Build Coastguard Worker         MediaProfiles::VideoEncoderCap* cap = createVideoEncoderCap(atts, natts);
737*ec779b8eSAndroid Build Coastguard Worker         if (cap != nullptr) {
738*ec779b8eSAndroid Build Coastguard Worker           profiles->mVideoEncoders.add(cap);
739*ec779b8eSAndroid Build Coastguard Worker         }
740*ec779b8eSAndroid Build Coastguard Worker     } else if (strcmp("AudioEncoderCap", name) == 0 &&
741*ec779b8eSAndroid Build Coastguard Worker                natts >= 4 &&
742*ec779b8eSAndroid Build Coastguard Worker                strcmp("true", atts[3]) == 0) {
743*ec779b8eSAndroid Build Coastguard Worker         MediaProfiles::AudioEncoderCap* cap = createAudioEncoderCap(atts, natts);
744*ec779b8eSAndroid Build Coastguard Worker         if (cap != nullptr) {
745*ec779b8eSAndroid Build Coastguard Worker           profiles->mAudioEncoders.add(cap);
746*ec779b8eSAndroid Build Coastguard Worker         }
747*ec779b8eSAndroid Build Coastguard Worker     } else if (strcmp("VideoDecoderCap", name) == 0 &&
748*ec779b8eSAndroid Build Coastguard Worker                natts >= 4 &&
749*ec779b8eSAndroid Build Coastguard Worker                strcmp("true", atts[3]) == 0) {
750*ec779b8eSAndroid Build Coastguard Worker         MediaProfiles::VideoDecoderCap* cap = createVideoDecoderCap(atts, natts);
751*ec779b8eSAndroid Build Coastguard Worker         if (cap != nullptr) {
752*ec779b8eSAndroid Build Coastguard Worker           profiles->mVideoDecoders.add(cap);
753*ec779b8eSAndroid Build Coastguard Worker         }
754*ec779b8eSAndroid Build Coastguard Worker     } else if (strcmp("AudioDecoderCap", name) == 0 &&
755*ec779b8eSAndroid Build Coastguard Worker                natts >= 4 &&
756*ec779b8eSAndroid Build Coastguard Worker                strcmp("true", atts[3]) == 0) {
757*ec779b8eSAndroid Build Coastguard Worker         MediaProfiles::AudioDecoderCap* cap = createAudioDecoderCap(atts, natts);
758*ec779b8eSAndroid Build Coastguard Worker         if (cap != nullptr) {
759*ec779b8eSAndroid Build Coastguard Worker           profiles->mAudioDecoders.add(cap);
760*ec779b8eSAndroid Build Coastguard Worker         }
761*ec779b8eSAndroid Build Coastguard Worker     } else if (strcmp("EncoderOutputFileFormat", name) == 0) {
762*ec779b8eSAndroid Build Coastguard Worker         profiles->mEncoderOutputFileFormats.add(createEncoderOutputFileFormat(atts, natts));
763*ec779b8eSAndroid Build Coastguard Worker     } else if (strcmp("CamcorderProfiles", name) == 0) {
764*ec779b8eSAndroid Build Coastguard Worker         profiles->mCurrentCameraId = getCameraId(atts, natts);
765*ec779b8eSAndroid Build Coastguard Worker         profiles->addStartTimeOffset(profiles->mCurrentCameraId, atts, natts);
766*ec779b8eSAndroid Build Coastguard Worker     } else if (strcmp("EncoderProfile", name) == 0) {
767*ec779b8eSAndroid Build Coastguard Worker       MediaProfiles::CamcorderProfile* profile = createCamcorderProfile(
768*ec779b8eSAndroid Build Coastguard Worker           profiles->mCurrentCameraId, atts, natts, profiles->mCameraIds);
769*ec779b8eSAndroid Build Coastguard Worker       if (profile != nullptr) {
770*ec779b8eSAndroid Build Coastguard Worker         profiles->mCamcorderProfiles.add(profile);
771*ec779b8eSAndroid Build Coastguard Worker       }
772*ec779b8eSAndroid Build Coastguard Worker     } else if (strcmp("ImageEncoding", name) == 0) {
773*ec779b8eSAndroid Build Coastguard Worker         profiles->addImageEncodingQualityLevel(profiles->mCurrentCameraId, atts, natts);
774*ec779b8eSAndroid Build Coastguard Worker     }
775*ec779b8eSAndroid Build Coastguard Worker }
776*ec779b8eSAndroid Build Coastguard Worker 
isCamcorderProfile(camcorder_quality quality)777*ec779b8eSAndroid Build Coastguard Worker static bool isCamcorderProfile(camcorder_quality quality) {
778*ec779b8eSAndroid Build Coastguard Worker     return quality >= CAMCORDER_QUALITY_LIST_START &&
779*ec779b8eSAndroid Build Coastguard Worker            quality <= CAMCORDER_QUALITY_LIST_END;
780*ec779b8eSAndroid Build Coastguard Worker }
781*ec779b8eSAndroid Build Coastguard Worker 
isTimelapseProfile(camcorder_quality quality)782*ec779b8eSAndroid Build Coastguard Worker static bool isTimelapseProfile(camcorder_quality quality) {
783*ec779b8eSAndroid Build Coastguard Worker     return quality >= CAMCORDER_QUALITY_TIME_LAPSE_LIST_START &&
784*ec779b8eSAndroid Build Coastguard Worker            quality <= CAMCORDER_QUALITY_TIME_LAPSE_LIST_END;
785*ec779b8eSAndroid Build Coastguard Worker }
786*ec779b8eSAndroid Build Coastguard Worker 
isHighSpeedProfile(camcorder_quality quality)787*ec779b8eSAndroid Build Coastguard Worker static bool isHighSpeedProfile(camcorder_quality quality) {
788*ec779b8eSAndroid Build Coastguard Worker     return quality >= CAMCORDER_QUALITY_HIGH_SPEED_LIST_START &&
789*ec779b8eSAndroid Build Coastguard Worker            quality <= CAMCORDER_QUALITY_HIGH_SPEED_LIST_END;
790*ec779b8eSAndroid Build Coastguard Worker }
791*ec779b8eSAndroid Build Coastguard Worker 
initRequiredProfileRefs(const Vector<int> & cameraIds)792*ec779b8eSAndroid Build Coastguard Worker void MediaProfiles::initRequiredProfileRefs(const Vector<int>& cameraIds) {
793*ec779b8eSAndroid Build Coastguard Worker     ALOGV("Number of camera ids: %zu", cameraIds.size());
794*ec779b8eSAndroid Build Coastguard Worker     CHECK(cameraIds.size() > 0);
795*ec779b8eSAndroid Build Coastguard Worker     mRequiredProfileRefs = new RequiredProfiles[cameraIds.size()];
796*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0, n = cameraIds.size(); i < n; ++i) {
797*ec779b8eSAndroid Build Coastguard Worker         mRequiredProfileRefs[i].mCameraId = cameraIds[i];
798*ec779b8eSAndroid Build Coastguard Worker         for (size_t j = 0; j < kNumRequiredProfiles; ++j) {
799*ec779b8eSAndroid Build Coastguard Worker             mRequiredProfileRefs[i].mRefs[j].mHasRefProfile = false;
800*ec779b8eSAndroid Build Coastguard Worker             mRequiredProfileRefs[i].mRefs[j].mRefProfileIndex = -1;
801*ec779b8eSAndroid Build Coastguard Worker             if ((j & 1) == 0) {  // low resolution
802*ec779b8eSAndroid Build Coastguard Worker                 mRequiredProfileRefs[i].mRefs[j].mResolutionProduct = 0x7FFFFFFF;
803*ec779b8eSAndroid Build Coastguard Worker             } else {             // high resolution
804*ec779b8eSAndroid Build Coastguard Worker                 mRequiredProfileRefs[i].mRefs[j].mResolutionProduct = 0;
805*ec779b8eSAndroid Build Coastguard Worker             }
806*ec779b8eSAndroid Build Coastguard Worker         }
807*ec779b8eSAndroid Build Coastguard Worker     }
808*ec779b8eSAndroid Build Coastguard Worker }
809*ec779b8eSAndroid Build Coastguard Worker 
getRequiredProfileRefIndex(int cameraId)810*ec779b8eSAndroid Build Coastguard Worker int MediaProfiles::getRequiredProfileRefIndex(int cameraId) {
811*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0, n = mCameraIds.size(); i < n; ++i) {
812*ec779b8eSAndroid Build Coastguard Worker         if (mCameraIds[i] == cameraId) {
813*ec779b8eSAndroid Build Coastguard Worker             return i;
814*ec779b8eSAndroid Build Coastguard Worker         }
815*ec779b8eSAndroid Build Coastguard Worker     }
816*ec779b8eSAndroid Build Coastguard Worker     return -1;
817*ec779b8eSAndroid Build Coastguard Worker }
818*ec779b8eSAndroid Build Coastguard Worker 
checkAndAddRequiredProfilesIfNecessary()819*ec779b8eSAndroid Build Coastguard Worker void MediaProfiles::checkAndAddRequiredProfilesIfNecessary() {
820*ec779b8eSAndroid Build Coastguard Worker     if (sIsInitialized) {
821*ec779b8eSAndroid Build Coastguard Worker         return;
822*ec779b8eSAndroid Build Coastguard Worker     }
823*ec779b8eSAndroid Build Coastguard Worker 
824*ec779b8eSAndroid Build Coastguard Worker     initRequiredProfileRefs(mCameraIds);
825*ec779b8eSAndroid Build Coastguard Worker 
826*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0, n = mCamcorderProfiles.size(); i < n; ++i) {
827*ec779b8eSAndroid Build Coastguard Worker         // ensure at least one video and audio profile is added
828*ec779b8eSAndroid Build Coastguard Worker         if (mCamcorderProfiles[i]->mVideoCodecs.empty()) {
829*ec779b8eSAndroid Build Coastguard Worker             mCamcorderProfiles[i]->mVideoCodecs.emplace_back(
830*ec779b8eSAndroid Build Coastguard Worker                     VIDEO_ENCODER_H263, 192000 /* bitrate */,
831*ec779b8eSAndroid Build Coastguard Worker                     176 /* width */, 144 /* height */, 20 /* frameRate */);
832*ec779b8eSAndroid Build Coastguard Worker         }
833*ec779b8eSAndroid Build Coastguard Worker         if (mCamcorderProfiles[i]->mAudioCodecs.empty()) {
834*ec779b8eSAndroid Build Coastguard Worker             mCamcorderProfiles[i]->mAudioCodecs.emplace_back(
835*ec779b8eSAndroid Build Coastguard Worker                     AUDIO_ENCODER_AMR_NB, 12200 /* bitrate */,
836*ec779b8eSAndroid Build Coastguard Worker                     8000 /* sampleRate */, 1 /* channels */);
837*ec779b8eSAndroid Build Coastguard Worker         }
838*ec779b8eSAndroid Build Coastguard Worker 
839*ec779b8eSAndroid Build Coastguard Worker         int product = mCamcorderProfiles[i]->mVideoCodecs[0].mFrameWidth *
840*ec779b8eSAndroid Build Coastguard Worker                       mCamcorderProfiles[i]->mVideoCodecs[0].mFrameHeight;
841*ec779b8eSAndroid Build Coastguard Worker 
842*ec779b8eSAndroid Build Coastguard Worker         camcorder_quality quality = mCamcorderProfiles[i]->mQuality;
843*ec779b8eSAndroid Build Coastguard Worker         int cameraId = mCamcorderProfiles[i]->mCameraId;
844*ec779b8eSAndroid Build Coastguard Worker         int index = -1;
845*ec779b8eSAndroid Build Coastguard Worker         int refIndex = getRequiredProfileRefIndex(cameraId);
846*ec779b8eSAndroid Build Coastguard Worker         CHECK(refIndex != -1);
847*ec779b8eSAndroid Build Coastguard Worker         RequiredProfileRefInfo *info;
848*ec779b8eSAndroid Build Coastguard Worker         camcorder_quality refQuality;
849*ec779b8eSAndroid Build Coastguard Worker 
850*ec779b8eSAndroid Build Coastguard Worker         // Check high and low from either camcorder profile, timelapse profile
851*ec779b8eSAndroid Build Coastguard Worker         // or high speed profile, but not all of them. Default, check camcorder profile
852*ec779b8eSAndroid Build Coastguard Worker         size_t j = 0;
853*ec779b8eSAndroid Build Coastguard Worker         size_t o = 2;
854*ec779b8eSAndroid Build Coastguard Worker         if (isTimelapseProfile(quality)) {
855*ec779b8eSAndroid Build Coastguard Worker             // Check timelapse profile instead.
856*ec779b8eSAndroid Build Coastguard Worker             j = 2;
857*ec779b8eSAndroid Build Coastguard Worker             o = kNumRequiredProfiles;
858*ec779b8eSAndroid Build Coastguard Worker         } else if (isHighSpeedProfile(quality)) {
859*ec779b8eSAndroid Build Coastguard Worker             // Skip the check for high speed profile.
860*ec779b8eSAndroid Build Coastguard Worker             continue;
861*ec779b8eSAndroid Build Coastguard Worker         } else {
862*ec779b8eSAndroid Build Coastguard Worker             // Must be camcorder profile.
863*ec779b8eSAndroid Build Coastguard Worker             CHECK(isCamcorderProfile(quality));
864*ec779b8eSAndroid Build Coastguard Worker         }
865*ec779b8eSAndroid Build Coastguard Worker         for (; j < o; ++j) {
866*ec779b8eSAndroid Build Coastguard Worker             info = &(mRequiredProfileRefs[refIndex].mRefs[j]);
867*ec779b8eSAndroid Build Coastguard Worker             if ((j % 2 == 0 && product > info->mResolutionProduct) ||  // low
868*ec779b8eSAndroid Build Coastguard Worker                 (j % 2 != 0 && product < info->mResolutionProduct)) {  // high
869*ec779b8eSAndroid Build Coastguard Worker                 continue;
870*ec779b8eSAndroid Build Coastguard Worker             }
871*ec779b8eSAndroid Build Coastguard Worker             switch (j) {
872*ec779b8eSAndroid Build Coastguard Worker                 case 0:
873*ec779b8eSAndroid Build Coastguard Worker                    refQuality = CAMCORDER_QUALITY_LOW;
874*ec779b8eSAndroid Build Coastguard Worker                    break;
875*ec779b8eSAndroid Build Coastguard Worker                 case 1:
876*ec779b8eSAndroid Build Coastguard Worker                    refQuality = CAMCORDER_QUALITY_HIGH;
877*ec779b8eSAndroid Build Coastguard Worker                    break;
878*ec779b8eSAndroid Build Coastguard Worker                 case 2:
879*ec779b8eSAndroid Build Coastguard Worker                    refQuality = CAMCORDER_QUALITY_TIME_LAPSE_LOW;
880*ec779b8eSAndroid Build Coastguard Worker                    break;
881*ec779b8eSAndroid Build Coastguard Worker                 case 3:
882*ec779b8eSAndroid Build Coastguard Worker                    refQuality = CAMCORDER_QUALITY_TIME_LAPSE_HIGH;
883*ec779b8eSAndroid Build Coastguard Worker                    break;
884*ec779b8eSAndroid Build Coastguard Worker                 default:
885*ec779b8eSAndroid Build Coastguard Worker                     CHECK(!"Should never reach here");
886*ec779b8eSAndroid Build Coastguard Worker             }
887*ec779b8eSAndroid Build Coastguard Worker 
888*ec779b8eSAndroid Build Coastguard Worker             if (!info->mHasRefProfile) {
889*ec779b8eSAndroid Build Coastguard Worker                 index = getCamcorderProfileIndex(cameraId, refQuality);
890*ec779b8eSAndroid Build Coastguard Worker             }
891*ec779b8eSAndroid Build Coastguard Worker             if (index == -1) {
892*ec779b8eSAndroid Build Coastguard Worker                 // New high or low quality profile is found.
893*ec779b8eSAndroid Build Coastguard Worker                 // Update its reference.
894*ec779b8eSAndroid Build Coastguard Worker                 info->mHasRefProfile = true;
895*ec779b8eSAndroid Build Coastguard Worker                 info->mRefProfileIndex = i;
896*ec779b8eSAndroid Build Coastguard Worker                 info->mResolutionProduct = product;
897*ec779b8eSAndroid Build Coastguard Worker             }
898*ec779b8eSAndroid Build Coastguard Worker         }
899*ec779b8eSAndroid Build Coastguard Worker     }
900*ec779b8eSAndroid Build Coastguard Worker 
901*ec779b8eSAndroid Build Coastguard Worker     for (size_t refIndex = 0; refIndex < mCameraIds.size(); ++refIndex) {
902*ec779b8eSAndroid Build Coastguard Worker         const int cameraId = mCameraIds[refIndex];
903*ec779b8eSAndroid Build Coastguard Worker         for (size_t j = 0; j < kNumRequiredProfiles; ++j) {
904*ec779b8eSAndroid Build Coastguard Worker             RequiredProfileRefInfo *info =
905*ec779b8eSAndroid Build Coastguard Worker                     &mRequiredProfileRefs[refIndex].mRefs[j];
906*ec779b8eSAndroid Build Coastguard Worker 
907*ec779b8eSAndroid Build Coastguard Worker             if (info->mHasRefProfile) {
908*ec779b8eSAndroid Build Coastguard Worker 
909*ec779b8eSAndroid Build Coastguard Worker                 std::unique_ptr<CamcorderProfile> profile =
910*ec779b8eSAndroid Build Coastguard Worker                     std::make_unique<CamcorderProfile>(
911*ec779b8eSAndroid Build Coastguard Worker                             *mCamcorderProfiles[info->mRefProfileIndex]);
912*ec779b8eSAndroid Build Coastguard Worker 
913*ec779b8eSAndroid Build Coastguard Worker                 // Overwrite the quality
914*ec779b8eSAndroid Build Coastguard Worker                 switch (j % kNumRequiredProfiles) {
915*ec779b8eSAndroid Build Coastguard Worker                     case 0:
916*ec779b8eSAndroid Build Coastguard Worker                         profile->mQuality = CAMCORDER_QUALITY_LOW;
917*ec779b8eSAndroid Build Coastguard Worker                         break;
918*ec779b8eSAndroid Build Coastguard Worker                     case 1:
919*ec779b8eSAndroid Build Coastguard Worker                         profile->mQuality = CAMCORDER_QUALITY_HIGH;
920*ec779b8eSAndroid Build Coastguard Worker                         break;
921*ec779b8eSAndroid Build Coastguard Worker                     case 2:
922*ec779b8eSAndroid Build Coastguard Worker                         profile->mQuality = CAMCORDER_QUALITY_TIME_LAPSE_LOW;
923*ec779b8eSAndroid Build Coastguard Worker                         break;
924*ec779b8eSAndroid Build Coastguard Worker                     case 3:
925*ec779b8eSAndroid Build Coastguard Worker                         profile->mQuality = CAMCORDER_QUALITY_TIME_LAPSE_HIGH;
926*ec779b8eSAndroid Build Coastguard Worker                         break;
927*ec779b8eSAndroid Build Coastguard Worker                     default:
928*ec779b8eSAndroid Build Coastguard Worker                         CHECK(!"Should never come here");
929*ec779b8eSAndroid Build Coastguard Worker                 }
930*ec779b8eSAndroid Build Coastguard Worker 
931*ec779b8eSAndroid Build Coastguard Worker                 int index = getCamcorderProfileIndex(cameraId, profile->mQuality);
932*ec779b8eSAndroid Build Coastguard Worker                 if (index != -1) {
933*ec779b8eSAndroid Build Coastguard Worker                     ALOGV("Profile quality %d for camera %d already exists",
934*ec779b8eSAndroid Build Coastguard Worker                         profile->mQuality, cameraId);
935*ec779b8eSAndroid Build Coastguard Worker                     CHECK(index == refIndex);
936*ec779b8eSAndroid Build Coastguard Worker                     continue;
937*ec779b8eSAndroid Build Coastguard Worker                 }
938*ec779b8eSAndroid Build Coastguard Worker 
939*ec779b8eSAndroid Build Coastguard Worker                 // Insert the new profile
940*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("Add a profile: quality %d=>%d for camera %d",
941*ec779b8eSAndroid Build Coastguard Worker                         mCamcorderProfiles[info->mRefProfileIndex]->mQuality,
942*ec779b8eSAndroid Build Coastguard Worker                         profile->mQuality, cameraId);
943*ec779b8eSAndroid Build Coastguard Worker 
944*ec779b8eSAndroid Build Coastguard Worker                 mCamcorderProfiles.add(profile.release());
945*ec779b8eSAndroid Build Coastguard Worker             }
946*ec779b8eSAndroid Build Coastguard Worker         }
947*ec779b8eSAndroid Build Coastguard Worker     }
948*ec779b8eSAndroid Build Coastguard Worker }
949*ec779b8eSAndroid Build Coastguard Worker 
950*ec779b8eSAndroid Build Coastguard Worker /*static*/ MediaProfiles*
getInstance()951*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::getInstance()
952*ec779b8eSAndroid Build Coastguard Worker {
953*ec779b8eSAndroid Build Coastguard Worker     ALOGV("getInstance");
954*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock lock(sLock);
955*ec779b8eSAndroid Build Coastguard Worker     if (!sIsInitialized) {
956*ec779b8eSAndroid Build Coastguard Worker         char value[PROPERTY_VALUE_MAX];
957*ec779b8eSAndroid Build Coastguard Worker         if (property_get("media.settings.xml", value, NULL) <= 0) {
958*ec779b8eSAndroid Build Coastguard Worker             const char* xmlFile = nullptr;
959*ec779b8eSAndroid Build Coastguard Worker             for (auto const& f : getXmlPaths()) {
960*ec779b8eSAndroid Build Coastguard Worker                 if (checkXmlFile(f)) {
961*ec779b8eSAndroid Build Coastguard Worker                     xmlFile = f;
962*ec779b8eSAndroid Build Coastguard Worker                     break;
963*ec779b8eSAndroid Build Coastguard Worker                 }
964*ec779b8eSAndroid Build Coastguard Worker             }
965*ec779b8eSAndroid Build Coastguard Worker             if (xmlFile == nullptr) {
966*ec779b8eSAndroid Build Coastguard Worker                 ALOGW("Could not find a validated xml file. "
967*ec779b8eSAndroid Build Coastguard Worker                         "Using the default instance instead.");
968*ec779b8eSAndroid Build Coastguard Worker                 sInstance = createDefaultInstance();
969*ec779b8eSAndroid Build Coastguard Worker             } else {
970*ec779b8eSAndroid Build Coastguard Worker                 sInstance = createInstanceFromXmlFile(xmlFile);
971*ec779b8eSAndroid Build Coastguard Worker             }
972*ec779b8eSAndroid Build Coastguard Worker         } else {
973*ec779b8eSAndroid Build Coastguard Worker             sInstance = createInstanceFromXmlFile(value);
974*ec779b8eSAndroid Build Coastguard Worker         }
975*ec779b8eSAndroid Build Coastguard Worker         CHECK(sInstance != NULL);
976*ec779b8eSAndroid Build Coastguard Worker         sInstance->checkAndAddRequiredProfilesIfNecessary();
977*ec779b8eSAndroid Build Coastguard Worker         sIsInitialized = true;
978*ec779b8eSAndroid Build Coastguard Worker     }
979*ec779b8eSAndroid Build Coastguard Worker 
980*ec779b8eSAndroid Build Coastguard Worker     return sInstance;
981*ec779b8eSAndroid Build Coastguard Worker }
982*ec779b8eSAndroid Build Coastguard Worker 
983*ec779b8eSAndroid Build Coastguard Worker /*static*/ MediaProfiles::VideoEncoderCap*
createDefaultH263VideoEncoderCap()984*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultH263VideoEncoderCap()
985*ec779b8eSAndroid Build Coastguard Worker {
986*ec779b8eSAndroid Build Coastguard Worker     return new MediaProfiles::VideoEncoderCap(
987*ec779b8eSAndroid Build Coastguard Worker         VIDEO_ENCODER_H263, 192000, 420000, 176, 352, 144, 288, 1, 20);
988*ec779b8eSAndroid Build Coastguard Worker }
989*ec779b8eSAndroid Build Coastguard Worker 
990*ec779b8eSAndroid Build Coastguard Worker /*static*/ MediaProfiles::VideoEncoderCap*
createDefaultM4vVideoEncoderCap()991*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultM4vVideoEncoderCap()
992*ec779b8eSAndroid Build Coastguard Worker {
993*ec779b8eSAndroid Build Coastguard Worker     return new MediaProfiles::VideoEncoderCap(
994*ec779b8eSAndroid Build Coastguard Worker         VIDEO_ENCODER_MPEG_4_SP, 192000, 420000, 176, 352, 144, 288, 1, 20);
995*ec779b8eSAndroid Build Coastguard Worker }
996*ec779b8eSAndroid Build Coastguard Worker 
997*ec779b8eSAndroid Build Coastguard Worker 
998*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
createDefaultVideoEncoders(MediaProfiles * profiles)999*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultVideoEncoders(MediaProfiles *profiles)
1000*ec779b8eSAndroid Build Coastguard Worker {
1001*ec779b8eSAndroid Build Coastguard Worker     profiles->mVideoEncoders.add(createDefaultH263VideoEncoderCap());
1002*ec779b8eSAndroid Build Coastguard Worker     profiles->mVideoEncoders.add(createDefaultM4vVideoEncoderCap());
1003*ec779b8eSAndroid Build Coastguard Worker }
1004*ec779b8eSAndroid Build Coastguard Worker 
1005*ec779b8eSAndroid Build Coastguard Worker /*static*/ MediaProfiles::CamcorderProfile*
createDefaultCamcorderTimeLapseQcifProfile(camcorder_quality quality)1006*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultCamcorderTimeLapseQcifProfile(camcorder_quality quality)
1007*ec779b8eSAndroid Build Coastguard Worker {
1008*ec779b8eSAndroid Build Coastguard Worker     CamcorderProfile *profile = new MediaProfiles::CamcorderProfile;
1009*ec779b8eSAndroid Build Coastguard Worker     profile->mCameraId = 0;
1010*ec779b8eSAndroid Build Coastguard Worker     profile->mFileFormat = OUTPUT_FORMAT_THREE_GPP;
1011*ec779b8eSAndroid Build Coastguard Worker     profile->mQuality = quality;
1012*ec779b8eSAndroid Build Coastguard Worker     profile->mDuration = 60;
1013*ec779b8eSAndroid Build Coastguard Worker     profile->mVideoCodecs.emplace_back(
1014*ec779b8eSAndroid Build Coastguard Worker             VIDEO_ENCODER_H263, 1000000 /* bitrate */,
1015*ec779b8eSAndroid Build Coastguard Worker             176 /* width */, 144 /* height */, 20 /* frameRate */);
1016*ec779b8eSAndroid Build Coastguard Worker     profile->mAudioCodecs.emplace_back(
1017*ec779b8eSAndroid Build Coastguard Worker             AUDIO_ENCODER_AMR_NB, 12200 /* bitrate */,
1018*ec779b8eSAndroid Build Coastguard Worker             8000 /* sampleRate */, 1 /* channels */);
1019*ec779b8eSAndroid Build Coastguard Worker 
1020*ec779b8eSAndroid Build Coastguard Worker     return profile;
1021*ec779b8eSAndroid Build Coastguard Worker }
1022*ec779b8eSAndroid Build Coastguard Worker 
1023*ec779b8eSAndroid Build Coastguard Worker /*static*/ MediaProfiles::CamcorderProfile*
createDefaultCamcorderTimeLapse480pProfile(camcorder_quality quality)1024*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultCamcorderTimeLapse480pProfile(camcorder_quality quality)
1025*ec779b8eSAndroid Build Coastguard Worker {
1026*ec779b8eSAndroid Build Coastguard Worker     CamcorderProfile *profile = new MediaProfiles::CamcorderProfile;
1027*ec779b8eSAndroid Build Coastguard Worker     profile->mCameraId = 0;
1028*ec779b8eSAndroid Build Coastguard Worker     profile->mFileFormat = OUTPUT_FORMAT_THREE_GPP;
1029*ec779b8eSAndroid Build Coastguard Worker     profile->mQuality = quality;
1030*ec779b8eSAndroid Build Coastguard Worker     profile->mDuration = 60;
1031*ec779b8eSAndroid Build Coastguard Worker     profile->mVideoCodecs.emplace_back(
1032*ec779b8eSAndroid Build Coastguard Worker             VIDEO_ENCODER_H263, 20000000 /* bitrate */,
1033*ec779b8eSAndroid Build Coastguard Worker             720 /* width */, 480 /* height */, 20 /* frameRate */);
1034*ec779b8eSAndroid Build Coastguard Worker     profile->mAudioCodecs.emplace_back(
1035*ec779b8eSAndroid Build Coastguard Worker             AUDIO_ENCODER_AMR_NB, 12200 /* bitrate */,
1036*ec779b8eSAndroid Build Coastguard Worker             8000 /* sampleRate */, 1 /* channels */);
1037*ec779b8eSAndroid Build Coastguard Worker     return profile;
1038*ec779b8eSAndroid Build Coastguard Worker }
1039*ec779b8eSAndroid Build Coastguard Worker 
1040*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
createDefaultCamcorderTimeLapseLowProfiles(MediaProfiles::CamcorderProfile ** lowTimeLapseProfile,MediaProfiles::CamcorderProfile ** lowSpecificTimeLapseProfile)1041*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultCamcorderTimeLapseLowProfiles(
1042*ec779b8eSAndroid Build Coastguard Worker         MediaProfiles::CamcorderProfile **lowTimeLapseProfile,
1043*ec779b8eSAndroid Build Coastguard Worker         MediaProfiles::CamcorderProfile **lowSpecificTimeLapseProfile) {
1044*ec779b8eSAndroid Build Coastguard Worker     *lowTimeLapseProfile = createDefaultCamcorderTimeLapseQcifProfile(
1045*ec779b8eSAndroid Build Coastguard Worker             CAMCORDER_QUALITY_TIME_LAPSE_LOW);
1046*ec779b8eSAndroid Build Coastguard Worker     *lowSpecificTimeLapseProfile = createDefaultCamcorderTimeLapseQcifProfile(
1047*ec779b8eSAndroid Build Coastguard Worker             CAMCORDER_QUALITY_TIME_LAPSE_QCIF);
1048*ec779b8eSAndroid Build Coastguard Worker }
1049*ec779b8eSAndroid Build Coastguard Worker 
1050*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
createDefaultCamcorderTimeLapseHighProfiles(MediaProfiles::CamcorderProfile ** highTimeLapseProfile,MediaProfiles::CamcorderProfile ** highSpecificTimeLapseProfile)1051*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultCamcorderTimeLapseHighProfiles(
1052*ec779b8eSAndroid Build Coastguard Worker         MediaProfiles::CamcorderProfile **highTimeLapseProfile,
1053*ec779b8eSAndroid Build Coastguard Worker         MediaProfiles::CamcorderProfile **highSpecificTimeLapseProfile) {
1054*ec779b8eSAndroid Build Coastguard Worker     *highTimeLapseProfile = createDefaultCamcorderTimeLapse480pProfile(
1055*ec779b8eSAndroid Build Coastguard Worker             CAMCORDER_QUALITY_TIME_LAPSE_HIGH);
1056*ec779b8eSAndroid Build Coastguard Worker     *highSpecificTimeLapseProfile = createDefaultCamcorderTimeLapse480pProfile(
1057*ec779b8eSAndroid Build Coastguard Worker             CAMCORDER_QUALITY_TIME_LAPSE_480P);
1058*ec779b8eSAndroid Build Coastguard Worker }
1059*ec779b8eSAndroid Build Coastguard Worker 
1060*ec779b8eSAndroid Build Coastguard Worker /*static*/ MediaProfiles::CamcorderProfile*
createDefaultCamcorderQcifProfile(camcorder_quality quality)1061*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultCamcorderQcifProfile(camcorder_quality quality)
1062*ec779b8eSAndroid Build Coastguard Worker {
1063*ec779b8eSAndroid Build Coastguard Worker     CamcorderProfile *profile = new MediaProfiles::CamcorderProfile;
1064*ec779b8eSAndroid Build Coastguard Worker     profile->mCameraId = 0;
1065*ec779b8eSAndroid Build Coastguard Worker     profile->mFileFormat = OUTPUT_FORMAT_THREE_GPP;
1066*ec779b8eSAndroid Build Coastguard Worker     profile->mQuality = quality;
1067*ec779b8eSAndroid Build Coastguard Worker     profile->mDuration = 30;
1068*ec779b8eSAndroid Build Coastguard Worker     profile->mVideoCodecs.emplace_back(
1069*ec779b8eSAndroid Build Coastguard Worker             VIDEO_ENCODER_H263, 192000 /* bitrate */,
1070*ec779b8eSAndroid Build Coastguard Worker             176 /* width */, 144 /* height */, 20 /* frameRate */);
1071*ec779b8eSAndroid Build Coastguard Worker     profile->mAudioCodecs.emplace_back(
1072*ec779b8eSAndroid Build Coastguard Worker             AUDIO_ENCODER_AMR_NB, 12200 /* bitrate */,
1073*ec779b8eSAndroid Build Coastguard Worker             8000 /* sampleRate */, 1 /* channels */);
1074*ec779b8eSAndroid Build Coastguard Worker     return profile;
1075*ec779b8eSAndroid Build Coastguard Worker }
1076*ec779b8eSAndroid Build Coastguard Worker 
1077*ec779b8eSAndroid Build Coastguard Worker /*static*/ MediaProfiles::CamcorderProfile*
createDefaultCamcorderCifProfile(camcorder_quality quality)1078*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultCamcorderCifProfile(camcorder_quality quality)
1079*ec779b8eSAndroid Build Coastguard Worker {
1080*ec779b8eSAndroid Build Coastguard Worker     CamcorderProfile *profile = new MediaProfiles::CamcorderProfile;
1081*ec779b8eSAndroid Build Coastguard Worker     profile->mCameraId = 0;
1082*ec779b8eSAndroid Build Coastguard Worker     profile->mFileFormat = OUTPUT_FORMAT_THREE_GPP;
1083*ec779b8eSAndroid Build Coastguard Worker     profile->mQuality = quality;
1084*ec779b8eSAndroid Build Coastguard Worker     profile->mDuration = 60;
1085*ec779b8eSAndroid Build Coastguard Worker     profile->mVideoCodecs.emplace_back(
1086*ec779b8eSAndroid Build Coastguard Worker             VIDEO_ENCODER_H263, 360000 /* bitrate */,
1087*ec779b8eSAndroid Build Coastguard Worker             352 /* width */, 288 /* height */, 20 /* frameRate */);
1088*ec779b8eSAndroid Build Coastguard Worker     profile->mAudioCodecs.emplace_back(
1089*ec779b8eSAndroid Build Coastguard Worker             AUDIO_ENCODER_AMR_NB, 12200 /* bitrate */,
1090*ec779b8eSAndroid Build Coastguard Worker             8000 /* sampleRate */, 1 /* channels */);
1091*ec779b8eSAndroid Build Coastguard Worker     return profile;
1092*ec779b8eSAndroid Build Coastguard Worker }
1093*ec779b8eSAndroid Build Coastguard Worker 
1094*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
createDefaultCamcorderLowProfiles(MediaProfiles::CamcorderProfile ** lowProfile,MediaProfiles::CamcorderProfile ** lowSpecificProfile)1095*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultCamcorderLowProfiles(
1096*ec779b8eSAndroid Build Coastguard Worker         MediaProfiles::CamcorderProfile **lowProfile,
1097*ec779b8eSAndroid Build Coastguard Worker         MediaProfiles::CamcorderProfile **lowSpecificProfile) {
1098*ec779b8eSAndroid Build Coastguard Worker     *lowProfile = createDefaultCamcorderQcifProfile(CAMCORDER_QUALITY_LOW);
1099*ec779b8eSAndroid Build Coastguard Worker     *lowSpecificProfile = createDefaultCamcorderQcifProfile(CAMCORDER_QUALITY_QCIF);
1100*ec779b8eSAndroid Build Coastguard Worker }
1101*ec779b8eSAndroid Build Coastguard Worker 
1102*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
createDefaultCamcorderHighProfiles(MediaProfiles::CamcorderProfile ** highProfile,MediaProfiles::CamcorderProfile ** highSpecificProfile)1103*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultCamcorderHighProfiles(
1104*ec779b8eSAndroid Build Coastguard Worker         MediaProfiles::CamcorderProfile **highProfile,
1105*ec779b8eSAndroid Build Coastguard Worker         MediaProfiles::CamcorderProfile **highSpecificProfile) {
1106*ec779b8eSAndroid Build Coastguard Worker     *highProfile = createDefaultCamcorderCifProfile(CAMCORDER_QUALITY_HIGH);
1107*ec779b8eSAndroid Build Coastguard Worker     *highSpecificProfile = createDefaultCamcorderCifProfile(CAMCORDER_QUALITY_CIF);
1108*ec779b8eSAndroid Build Coastguard Worker }
1109*ec779b8eSAndroid Build Coastguard Worker 
1110*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
createDefaultCamcorderProfiles(MediaProfiles * profiles)1111*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultCamcorderProfiles(MediaProfiles *profiles)
1112*ec779b8eSAndroid Build Coastguard Worker {
1113*ec779b8eSAndroid Build Coastguard Worker     // low camcorder profiles.
1114*ec779b8eSAndroid Build Coastguard Worker     MediaProfiles::CamcorderProfile *lowProfile, *lowSpecificProfile;
1115*ec779b8eSAndroid Build Coastguard Worker     createDefaultCamcorderLowProfiles(&lowProfile, &lowSpecificProfile);
1116*ec779b8eSAndroid Build Coastguard Worker     profiles->mCamcorderProfiles.add(lowProfile);
1117*ec779b8eSAndroid Build Coastguard Worker     profiles->mCamcorderProfiles.add(lowSpecificProfile);
1118*ec779b8eSAndroid Build Coastguard Worker 
1119*ec779b8eSAndroid Build Coastguard Worker     // high camcorder profiles.
1120*ec779b8eSAndroid Build Coastguard Worker     MediaProfiles::CamcorderProfile* highProfile, *highSpecificProfile;
1121*ec779b8eSAndroid Build Coastguard Worker     createDefaultCamcorderHighProfiles(&highProfile, &highSpecificProfile);
1122*ec779b8eSAndroid Build Coastguard Worker     profiles->mCamcorderProfiles.add(highProfile);
1123*ec779b8eSAndroid Build Coastguard Worker     profiles->mCamcorderProfiles.add(highSpecificProfile);
1124*ec779b8eSAndroid Build Coastguard Worker 
1125*ec779b8eSAndroid Build Coastguard Worker     // low camcorder time lapse profiles.
1126*ec779b8eSAndroid Build Coastguard Worker     MediaProfiles::CamcorderProfile *lowTimeLapseProfile, *lowSpecificTimeLapseProfile;
1127*ec779b8eSAndroid Build Coastguard Worker     createDefaultCamcorderTimeLapseLowProfiles(&lowTimeLapseProfile, &lowSpecificTimeLapseProfile);
1128*ec779b8eSAndroid Build Coastguard Worker     profiles->mCamcorderProfiles.add(lowTimeLapseProfile);
1129*ec779b8eSAndroid Build Coastguard Worker     profiles->mCamcorderProfiles.add(lowSpecificTimeLapseProfile);
1130*ec779b8eSAndroid Build Coastguard Worker 
1131*ec779b8eSAndroid Build Coastguard Worker     // high camcorder time lapse profiles.
1132*ec779b8eSAndroid Build Coastguard Worker     MediaProfiles::CamcorderProfile *highTimeLapseProfile, *highSpecificTimeLapseProfile;
1133*ec779b8eSAndroid Build Coastguard Worker     createDefaultCamcorderTimeLapseHighProfiles(&highTimeLapseProfile,
1134*ec779b8eSAndroid Build Coastguard Worker             &highSpecificTimeLapseProfile);
1135*ec779b8eSAndroid Build Coastguard Worker     profiles->mCamcorderProfiles.add(highTimeLapseProfile);
1136*ec779b8eSAndroid Build Coastguard Worker     profiles->mCamcorderProfiles.add(highSpecificTimeLapseProfile);
1137*ec779b8eSAndroid Build Coastguard Worker 
1138*ec779b8eSAndroid Build Coastguard Worker     // For emulator and other legacy devices which does not have a
1139*ec779b8eSAndroid Build Coastguard Worker     // media_profiles.xml file, We assume that the default camera id
1140*ec779b8eSAndroid Build Coastguard Worker     // is 0 and that is the only camera available.
1141*ec779b8eSAndroid Build Coastguard Worker     profiles->mCameraIds.push(0);
1142*ec779b8eSAndroid Build Coastguard Worker }
1143*ec779b8eSAndroid Build Coastguard Worker 
1144*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
createDefaultAudioEncoders(MediaProfiles * profiles)1145*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultAudioEncoders(MediaProfiles *profiles)
1146*ec779b8eSAndroid Build Coastguard Worker {
1147*ec779b8eSAndroid Build Coastguard Worker     profiles->mAudioEncoders.add(createDefaultAmrNBEncoderCap());
1148*ec779b8eSAndroid Build Coastguard Worker }
1149*ec779b8eSAndroid Build Coastguard Worker 
1150*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
createDefaultVideoDecoders(MediaProfiles * profiles)1151*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultVideoDecoders(MediaProfiles *profiles)
1152*ec779b8eSAndroid Build Coastguard Worker {
1153*ec779b8eSAndroid Build Coastguard Worker     MediaProfiles::VideoDecoderCap *cap =
1154*ec779b8eSAndroid Build Coastguard Worker         new MediaProfiles::VideoDecoderCap(VIDEO_DECODER_WMV);
1155*ec779b8eSAndroid Build Coastguard Worker 
1156*ec779b8eSAndroid Build Coastguard Worker     profiles->mVideoDecoders.add(cap);
1157*ec779b8eSAndroid Build Coastguard Worker }
1158*ec779b8eSAndroid Build Coastguard Worker 
1159*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
createDefaultAudioDecoders(MediaProfiles * profiles)1160*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultAudioDecoders(MediaProfiles *profiles)
1161*ec779b8eSAndroid Build Coastguard Worker {
1162*ec779b8eSAndroid Build Coastguard Worker     MediaProfiles::AudioDecoderCap *cap =
1163*ec779b8eSAndroid Build Coastguard Worker         new MediaProfiles::AudioDecoderCap(AUDIO_DECODER_WMA);
1164*ec779b8eSAndroid Build Coastguard Worker 
1165*ec779b8eSAndroid Build Coastguard Worker     profiles->mAudioDecoders.add(cap);
1166*ec779b8eSAndroid Build Coastguard Worker }
1167*ec779b8eSAndroid Build Coastguard Worker 
1168*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
createDefaultEncoderOutputFileFormats(MediaProfiles * profiles)1169*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultEncoderOutputFileFormats(MediaProfiles *profiles)
1170*ec779b8eSAndroid Build Coastguard Worker {
1171*ec779b8eSAndroid Build Coastguard Worker     profiles->mEncoderOutputFileFormats.add(OUTPUT_FORMAT_THREE_GPP);
1172*ec779b8eSAndroid Build Coastguard Worker     profiles->mEncoderOutputFileFormats.add(OUTPUT_FORMAT_MPEG_4);
1173*ec779b8eSAndroid Build Coastguard Worker }
1174*ec779b8eSAndroid Build Coastguard Worker 
1175*ec779b8eSAndroid Build Coastguard Worker /*static*/ MediaProfiles::AudioEncoderCap*
createDefaultAmrNBEncoderCap()1176*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultAmrNBEncoderCap()
1177*ec779b8eSAndroid Build Coastguard Worker {
1178*ec779b8eSAndroid Build Coastguard Worker     return new MediaProfiles::AudioEncoderCap(
1179*ec779b8eSAndroid Build Coastguard Worker         AUDIO_ENCODER_AMR_NB, 5525, 12200, 8000, 8000, 1, 1);
1180*ec779b8eSAndroid Build Coastguard Worker }
1181*ec779b8eSAndroid Build Coastguard Worker 
1182*ec779b8eSAndroid Build Coastguard Worker /*static*/ void
createDefaultImageEncodingQualityLevels(MediaProfiles * profiles)1183*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultImageEncodingQualityLevels(MediaProfiles *profiles)
1184*ec779b8eSAndroid Build Coastguard Worker {
1185*ec779b8eSAndroid Build Coastguard Worker     ImageEncodingQualityLevels *levels = new ImageEncodingQualityLevels();
1186*ec779b8eSAndroid Build Coastguard Worker     levels->mCameraId = 0;
1187*ec779b8eSAndroid Build Coastguard Worker     levels->mLevels.add(70);
1188*ec779b8eSAndroid Build Coastguard Worker     levels->mLevels.add(80);
1189*ec779b8eSAndroid Build Coastguard Worker     levels->mLevels.add(90);
1190*ec779b8eSAndroid Build Coastguard Worker     profiles->mImageEncodingQualityLevels.add(levels);
1191*ec779b8eSAndroid Build Coastguard Worker }
1192*ec779b8eSAndroid Build Coastguard Worker 
1193*ec779b8eSAndroid Build Coastguard Worker /*static*/ MediaProfiles*
createDefaultInstance()1194*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createDefaultInstance()
1195*ec779b8eSAndroid Build Coastguard Worker {
1196*ec779b8eSAndroid Build Coastguard Worker     MediaProfiles *profiles = new MediaProfiles;
1197*ec779b8eSAndroid Build Coastguard Worker     createDefaultCamcorderProfiles(profiles);
1198*ec779b8eSAndroid Build Coastguard Worker     createDefaultVideoEncoders(profiles);
1199*ec779b8eSAndroid Build Coastguard Worker     createDefaultAudioEncoders(profiles);
1200*ec779b8eSAndroid Build Coastguard Worker     createDefaultVideoDecoders(profiles);
1201*ec779b8eSAndroid Build Coastguard Worker     createDefaultAudioDecoders(profiles);
1202*ec779b8eSAndroid Build Coastguard Worker     createDefaultEncoderOutputFileFormats(profiles);
1203*ec779b8eSAndroid Build Coastguard Worker     createDefaultImageEncodingQualityLevels(profiles);
1204*ec779b8eSAndroid Build Coastguard Worker     return profiles;
1205*ec779b8eSAndroid Build Coastguard Worker }
1206*ec779b8eSAndroid Build Coastguard Worker 
checkXmlFile(const char * xmlFile)1207*ec779b8eSAndroid Build Coastguard Worker bool MediaProfiles::checkXmlFile(const char* xmlFile) {
1208*ec779b8eSAndroid Build Coastguard Worker     struct stat fStat;
1209*ec779b8eSAndroid Build Coastguard Worker     return stat(xmlFile, &fStat) == 0 && S_ISREG(fStat.st_mode);
1210*ec779b8eSAndroid Build Coastguard Worker     // TODO: Add validation
1211*ec779b8eSAndroid Build Coastguard Worker }
1212*ec779b8eSAndroid Build Coastguard Worker 
1213*ec779b8eSAndroid Build Coastguard Worker /*static*/ MediaProfiles*
createInstanceFromXmlFile(const char * xml)1214*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::createInstanceFromXmlFile(const char *xml)
1215*ec779b8eSAndroid Build Coastguard Worker {
1216*ec779b8eSAndroid Build Coastguard Worker     FILE *fp = NULL;
1217*ec779b8eSAndroid Build Coastguard Worker     CHECK((fp = fopen(xml, "r")));
1218*ec779b8eSAndroid Build Coastguard Worker 
1219*ec779b8eSAndroid Build Coastguard Worker     XML_Parser parser = ::XML_ParserCreate(NULL);
1220*ec779b8eSAndroid Build Coastguard Worker     CHECK(parser != NULL);
1221*ec779b8eSAndroid Build Coastguard Worker 
1222*ec779b8eSAndroid Build Coastguard Worker     MediaProfiles *profiles = new MediaProfiles();
1223*ec779b8eSAndroid Build Coastguard Worker     ::XML_SetUserData(parser, profiles);
1224*ec779b8eSAndroid Build Coastguard Worker     ::XML_SetElementHandler(parser, startElementHandler, NULL);
1225*ec779b8eSAndroid Build Coastguard Worker 
1226*ec779b8eSAndroid Build Coastguard Worker     /*
1227*ec779b8eSAndroid Build Coastguard Worker       FIXME:
1228*ec779b8eSAndroid Build Coastguard Worker       expat is not compiled with -DXML_DTD. We don't have DTD parsing support.
1229*ec779b8eSAndroid Build Coastguard Worker 
1230*ec779b8eSAndroid Build Coastguard Worker       if (!::XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS)) {
1231*ec779b8eSAndroid Build Coastguard Worker           ALOGE("failed to enable DTD support in the xml file");
1232*ec779b8eSAndroid Build Coastguard Worker           return UNKNOWN_ERROR;
1233*ec779b8eSAndroid Build Coastguard Worker       }
1234*ec779b8eSAndroid Build Coastguard Worker 
1235*ec779b8eSAndroid Build Coastguard Worker     */
1236*ec779b8eSAndroid Build Coastguard Worker 
1237*ec779b8eSAndroid Build Coastguard Worker     const int BUFF_SIZE = 512;
1238*ec779b8eSAndroid Build Coastguard Worker     for (;;) {
1239*ec779b8eSAndroid Build Coastguard Worker         void *buff = ::XML_GetBuffer(parser, BUFF_SIZE);
1240*ec779b8eSAndroid Build Coastguard Worker         if (buff == NULL) {
1241*ec779b8eSAndroid Build Coastguard Worker             ALOGE("failed to in call to XML_GetBuffer()");
1242*ec779b8eSAndroid Build Coastguard Worker             delete profiles;
1243*ec779b8eSAndroid Build Coastguard Worker             profiles = NULL;
1244*ec779b8eSAndroid Build Coastguard Worker             goto exit;
1245*ec779b8eSAndroid Build Coastguard Worker         }
1246*ec779b8eSAndroid Build Coastguard Worker 
1247*ec779b8eSAndroid Build Coastguard Worker         int bytes_read = ::fread(buff, 1, BUFF_SIZE, fp);
1248*ec779b8eSAndroid Build Coastguard Worker         if (bytes_read < 0) {
1249*ec779b8eSAndroid Build Coastguard Worker             ALOGE("failed in call to read");
1250*ec779b8eSAndroid Build Coastguard Worker             delete profiles;
1251*ec779b8eSAndroid Build Coastguard Worker             profiles = NULL;
1252*ec779b8eSAndroid Build Coastguard Worker             goto exit;
1253*ec779b8eSAndroid Build Coastguard Worker         }
1254*ec779b8eSAndroid Build Coastguard Worker 
1255*ec779b8eSAndroid Build Coastguard Worker         CHECK(::XML_ParseBuffer(parser, bytes_read, bytes_read == 0));
1256*ec779b8eSAndroid Build Coastguard Worker 
1257*ec779b8eSAndroid Build Coastguard Worker         if (bytes_read == 0) break;  // done parsing the xml file
1258*ec779b8eSAndroid Build Coastguard Worker     }
1259*ec779b8eSAndroid Build Coastguard Worker 
1260*ec779b8eSAndroid Build Coastguard Worker exit:
1261*ec779b8eSAndroid Build Coastguard Worker     ::XML_ParserFree(parser);
1262*ec779b8eSAndroid Build Coastguard Worker     ::fclose(fp);
1263*ec779b8eSAndroid Build Coastguard Worker     return profiles;
1264*ec779b8eSAndroid Build Coastguard Worker }
1265*ec779b8eSAndroid Build Coastguard Worker 
getOutputFileFormats() const1266*ec779b8eSAndroid Build Coastguard Worker Vector<output_format> MediaProfiles::getOutputFileFormats() const
1267*ec779b8eSAndroid Build Coastguard Worker {
1268*ec779b8eSAndroid Build Coastguard Worker     return mEncoderOutputFileFormats;  // copy out
1269*ec779b8eSAndroid Build Coastguard Worker }
1270*ec779b8eSAndroid Build Coastguard Worker 
getVideoEncoders() const1271*ec779b8eSAndroid Build Coastguard Worker Vector<video_encoder> MediaProfiles::getVideoEncoders() const
1272*ec779b8eSAndroid Build Coastguard Worker {
1273*ec779b8eSAndroid Build Coastguard Worker     Vector<video_encoder> encoders;
1274*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mVideoEncoders.size(); ++i) {
1275*ec779b8eSAndroid Build Coastguard Worker         encoders.add(mVideoEncoders[i]->mCodec);
1276*ec779b8eSAndroid Build Coastguard Worker     }
1277*ec779b8eSAndroid Build Coastguard Worker     return encoders;  // copy out
1278*ec779b8eSAndroid Build Coastguard Worker }
1279*ec779b8eSAndroid Build Coastguard Worker 
getVideoEncoderParamByName(const char * name,video_encoder codec) const1280*ec779b8eSAndroid Build Coastguard Worker int MediaProfiles::getVideoEncoderParamByName(const char *name, video_encoder codec) const
1281*ec779b8eSAndroid Build Coastguard Worker {
1282*ec779b8eSAndroid Build Coastguard Worker     ALOGV("getVideoEncoderParamByName: %s for codec %d", name, codec);
1283*ec779b8eSAndroid Build Coastguard Worker     int index = -1;
1284*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0, n = mVideoEncoders.size(); i < n; ++i) {
1285*ec779b8eSAndroid Build Coastguard Worker         if (mVideoEncoders[i]->mCodec == codec) {
1286*ec779b8eSAndroid Build Coastguard Worker             index = i;
1287*ec779b8eSAndroid Build Coastguard Worker             break;
1288*ec779b8eSAndroid Build Coastguard Worker         }
1289*ec779b8eSAndroid Build Coastguard Worker     }
1290*ec779b8eSAndroid Build Coastguard Worker     if (index == -1) {
1291*ec779b8eSAndroid Build Coastguard Worker         ALOGE("The given video encoder %d is not found", codec);
1292*ec779b8eSAndroid Build Coastguard Worker         return -1;
1293*ec779b8eSAndroid Build Coastguard Worker     }
1294*ec779b8eSAndroid Build Coastguard Worker 
1295*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("enc.vid.width.min", name)) return mVideoEncoders[index]->mMinFrameWidth;
1296*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("enc.vid.width.max", name)) return mVideoEncoders[index]->mMaxFrameWidth;
1297*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("enc.vid.height.min", name)) return mVideoEncoders[index]->mMinFrameHeight;
1298*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("enc.vid.height.max", name)) return mVideoEncoders[index]->mMaxFrameHeight;
1299*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("enc.vid.bps.min", name)) return mVideoEncoders[index]->mMinBitRate;
1300*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("enc.vid.bps.max", name)) return mVideoEncoders[index]->mMaxBitRate;
1301*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("enc.vid.fps.min", name)) return mVideoEncoders[index]->mMinFrameRate;
1302*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("enc.vid.fps.max", name)) return mVideoEncoders[index]->mMaxFrameRate;
1303*ec779b8eSAndroid Build Coastguard Worker 
1304*ec779b8eSAndroid Build Coastguard Worker     ALOGE("The given video encoder param name %s is not found", name);
1305*ec779b8eSAndroid Build Coastguard Worker     return -1;
1306*ec779b8eSAndroid Build Coastguard Worker }
1307*ec779b8eSAndroid Build Coastguard Worker 
getAudioEncoders() const1308*ec779b8eSAndroid Build Coastguard Worker Vector<audio_encoder> MediaProfiles::getAudioEncoders() const
1309*ec779b8eSAndroid Build Coastguard Worker {
1310*ec779b8eSAndroid Build Coastguard Worker     Vector<audio_encoder> encoders;
1311*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mAudioEncoders.size(); ++i) {
1312*ec779b8eSAndroid Build Coastguard Worker         encoders.add(mAudioEncoders[i]->mCodec);
1313*ec779b8eSAndroid Build Coastguard Worker     }
1314*ec779b8eSAndroid Build Coastguard Worker     return encoders;  // copy out
1315*ec779b8eSAndroid Build Coastguard Worker }
1316*ec779b8eSAndroid Build Coastguard Worker 
getAudioEncoderParamByName(const char * name,audio_encoder codec) const1317*ec779b8eSAndroid Build Coastguard Worker int MediaProfiles::getAudioEncoderParamByName(const char *name, audio_encoder codec) const
1318*ec779b8eSAndroid Build Coastguard Worker {
1319*ec779b8eSAndroid Build Coastguard Worker     ALOGV("getAudioEncoderParamByName: %s for codec %d", name, codec);
1320*ec779b8eSAndroid Build Coastguard Worker     int index = -1;
1321*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0, n = mAudioEncoders.size(); i < n; ++i) {
1322*ec779b8eSAndroid Build Coastguard Worker         if (mAudioEncoders[i]->mCodec == codec) {
1323*ec779b8eSAndroid Build Coastguard Worker             index = i;
1324*ec779b8eSAndroid Build Coastguard Worker             break;
1325*ec779b8eSAndroid Build Coastguard Worker         }
1326*ec779b8eSAndroid Build Coastguard Worker     }
1327*ec779b8eSAndroid Build Coastguard Worker     if (index == -1) {
1328*ec779b8eSAndroid Build Coastguard Worker         ALOGE("The given audio encoder %d is not found", codec);
1329*ec779b8eSAndroid Build Coastguard Worker         return -1;
1330*ec779b8eSAndroid Build Coastguard Worker     }
1331*ec779b8eSAndroid Build Coastguard Worker 
1332*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("enc.aud.ch.min", name)) return mAudioEncoders[index]->mMinChannels;
1333*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("enc.aud.ch.max", name)) return mAudioEncoders[index]->mMaxChannels;
1334*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("enc.aud.bps.min", name)) return mAudioEncoders[index]->mMinBitRate;
1335*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("enc.aud.bps.max", name)) return mAudioEncoders[index]->mMaxBitRate;
1336*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("enc.aud.hz.min", name)) return mAudioEncoders[index]->mMinSampleRate;
1337*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("enc.aud.hz.max", name)) return mAudioEncoders[index]->mMaxSampleRate;
1338*ec779b8eSAndroid Build Coastguard Worker 
1339*ec779b8eSAndroid Build Coastguard Worker     ALOGE("The given audio encoder param name %s is not found", name);
1340*ec779b8eSAndroid Build Coastguard Worker     return -1;
1341*ec779b8eSAndroid Build Coastguard Worker }
1342*ec779b8eSAndroid Build Coastguard Worker 
getVideoDecoders() const1343*ec779b8eSAndroid Build Coastguard Worker Vector<video_decoder> MediaProfiles::getVideoDecoders() const
1344*ec779b8eSAndroid Build Coastguard Worker {
1345*ec779b8eSAndroid Build Coastguard Worker     Vector<video_decoder> decoders;
1346*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mVideoDecoders.size(); ++i) {
1347*ec779b8eSAndroid Build Coastguard Worker         decoders.add(mVideoDecoders[i]->mCodec);
1348*ec779b8eSAndroid Build Coastguard Worker     }
1349*ec779b8eSAndroid Build Coastguard Worker     return decoders;  // copy out
1350*ec779b8eSAndroid Build Coastguard Worker }
1351*ec779b8eSAndroid Build Coastguard Worker 
getAudioDecoders() const1352*ec779b8eSAndroid Build Coastguard Worker Vector<audio_decoder> MediaProfiles::getAudioDecoders() const
1353*ec779b8eSAndroid Build Coastguard Worker {
1354*ec779b8eSAndroid Build Coastguard Worker     Vector<audio_decoder> decoders;
1355*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mAudioDecoders.size(); ++i) {
1356*ec779b8eSAndroid Build Coastguard Worker         decoders.add(mAudioDecoders[i]->mCodec);
1357*ec779b8eSAndroid Build Coastguard Worker     }
1358*ec779b8eSAndroid Build Coastguard Worker     return decoders;  // copy out
1359*ec779b8eSAndroid Build Coastguard Worker }
1360*ec779b8eSAndroid Build Coastguard Worker 
getCamcorderProfileIndex(int cameraId,camcorder_quality quality) const1361*ec779b8eSAndroid Build Coastguard Worker int MediaProfiles::getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const
1362*ec779b8eSAndroid Build Coastguard Worker {
1363*ec779b8eSAndroid Build Coastguard Worker     int index = -1;
1364*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0, n = mCamcorderProfiles.size(); i < n; ++i) {
1365*ec779b8eSAndroid Build Coastguard Worker         if (mCamcorderProfiles[i]->mCameraId == cameraId &&
1366*ec779b8eSAndroid Build Coastguard Worker             mCamcorderProfiles[i]->mQuality == quality) {
1367*ec779b8eSAndroid Build Coastguard Worker             index = i;
1368*ec779b8eSAndroid Build Coastguard Worker             break;
1369*ec779b8eSAndroid Build Coastguard Worker         }
1370*ec779b8eSAndroid Build Coastguard Worker     }
1371*ec779b8eSAndroid Build Coastguard Worker     return index;
1372*ec779b8eSAndroid Build Coastguard Worker }
1373*ec779b8eSAndroid Build Coastguard Worker 
getCamcorderProfile(int cameraId,camcorder_quality quality) const1374*ec779b8eSAndroid Build Coastguard Worker const MediaProfiles::CamcorderProfile *MediaProfiles::getCamcorderProfile(
1375*ec779b8eSAndroid Build Coastguard Worker             int cameraId, camcorder_quality quality) const {
1376*ec779b8eSAndroid Build Coastguard Worker     int index = getCamcorderProfileIndex(cameraId, quality);
1377*ec779b8eSAndroid Build Coastguard Worker     if (index == -1) {
1378*ec779b8eSAndroid Build Coastguard Worker         ALOGE("The given camcorder profile camera %d quality %d is not found",
1379*ec779b8eSAndroid Build Coastguard Worker             cameraId, quality);
1380*ec779b8eSAndroid Build Coastguard Worker         return nullptr;
1381*ec779b8eSAndroid Build Coastguard Worker     }
1382*ec779b8eSAndroid Build Coastguard Worker 
1383*ec779b8eSAndroid Build Coastguard Worker     return mCamcorderProfiles[index];
1384*ec779b8eSAndroid Build Coastguard Worker }
1385*ec779b8eSAndroid Build Coastguard Worker 
1386*ec779b8eSAndroid Build Coastguard Worker std::vector<const MediaProfiles::AudioCodec *>
getAudioCodecs() const1387*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::CamcorderProfile::getAudioCodecs() const {
1388*ec779b8eSAndroid Build Coastguard Worker     std::vector<const MediaProfiles::AudioCodec *> res;
1389*ec779b8eSAndroid Build Coastguard Worker     for (const MediaProfiles::AudioCodec &ac : mAudioCodecs) {
1390*ec779b8eSAndroid Build Coastguard Worker         res.push_back(&ac);
1391*ec779b8eSAndroid Build Coastguard Worker     }
1392*ec779b8eSAndroid Build Coastguard Worker     return res;
1393*ec779b8eSAndroid Build Coastguard Worker }
1394*ec779b8eSAndroid Build Coastguard Worker 
1395*ec779b8eSAndroid Build Coastguard Worker std::vector<const MediaProfiles::VideoCodec *>
getVideoCodecs() const1396*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::CamcorderProfile::getVideoCodecs() const {
1397*ec779b8eSAndroid Build Coastguard Worker     std::vector<const MediaProfiles::VideoCodec *> res;
1398*ec779b8eSAndroid Build Coastguard Worker     for (const MediaProfiles::VideoCodec &vc : mVideoCodecs) {
1399*ec779b8eSAndroid Build Coastguard Worker         res.push_back(&vc);
1400*ec779b8eSAndroid Build Coastguard Worker     }
1401*ec779b8eSAndroid Build Coastguard Worker     return res;
1402*ec779b8eSAndroid Build Coastguard Worker }
1403*ec779b8eSAndroid Build Coastguard Worker 
getCamcorderProfileParamByName(const char * name,int cameraId,camcorder_quality quality) const1404*ec779b8eSAndroid Build Coastguard Worker int MediaProfiles::getCamcorderProfileParamByName(const char *name,
1405*ec779b8eSAndroid Build Coastguard Worker                                                   int cameraId,
1406*ec779b8eSAndroid Build Coastguard Worker                                                   camcorder_quality quality) const
1407*ec779b8eSAndroid Build Coastguard Worker {
1408*ec779b8eSAndroid Build Coastguard Worker     ALOGV("getCamcorderProfileParamByName: %s for camera %d, quality %d",
1409*ec779b8eSAndroid Build Coastguard Worker         name, cameraId, quality);
1410*ec779b8eSAndroid Build Coastguard Worker 
1411*ec779b8eSAndroid Build Coastguard Worker     int index = getCamcorderProfileIndex(cameraId, quality);
1412*ec779b8eSAndroid Build Coastguard Worker     if (index == -1) {
1413*ec779b8eSAndroid Build Coastguard Worker         ALOGE("The given camcorder profile camera %d quality %d is not found",
1414*ec779b8eSAndroid Build Coastguard Worker             cameraId, quality);
1415*ec779b8eSAndroid Build Coastguard Worker         return -1;
1416*ec779b8eSAndroid Build Coastguard Worker     }
1417*ec779b8eSAndroid Build Coastguard Worker 
1418*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("duration", name)) return mCamcorderProfiles[index]->mDuration;
1419*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("file.format", name)) return mCamcorderProfiles[index]->mFileFormat;
1420*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("vid.codec", name)) return mCamcorderProfiles[index]->mVideoCodecs[0].mCodec;
1421*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("vid.width", name)) return mCamcorderProfiles[index]->mVideoCodecs[0].mFrameWidth;
1422*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("vid.height", name)) return mCamcorderProfiles[index]->mVideoCodecs[0].mFrameHeight;
1423*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("vid.bps", name)) return mCamcorderProfiles[index]->mVideoCodecs[0].mBitRate;
1424*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("vid.fps", name)) return mCamcorderProfiles[index]->mVideoCodecs[0].mFrameRate;
1425*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("aud.codec", name)) return mCamcorderProfiles[index]->mAudioCodecs[0].mCodec;
1426*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("aud.bps", name)) return mCamcorderProfiles[index]->mAudioCodecs[0].mBitRate;
1427*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("aud.ch", name)) return mCamcorderProfiles[index]->mAudioCodecs[0].mChannels;
1428*ec779b8eSAndroid Build Coastguard Worker     if (!strcmp("aud.hz", name)) return mCamcorderProfiles[index]->mAudioCodecs[0].mSampleRate;
1429*ec779b8eSAndroid Build Coastguard Worker 
1430*ec779b8eSAndroid Build Coastguard Worker     ALOGE("The given camcorder profile param id %d name %s is not found", cameraId, name);
1431*ec779b8eSAndroid Build Coastguard Worker     return -1;
1432*ec779b8eSAndroid Build Coastguard Worker }
1433*ec779b8eSAndroid Build Coastguard Worker 
hasCamcorderProfile(int cameraId,camcorder_quality quality) const1434*ec779b8eSAndroid Build Coastguard Worker bool MediaProfiles::hasCamcorderProfile(int cameraId, camcorder_quality quality) const
1435*ec779b8eSAndroid Build Coastguard Worker {
1436*ec779b8eSAndroid Build Coastguard Worker     return (getCamcorderProfileIndex(cameraId, quality) != -1);
1437*ec779b8eSAndroid Build Coastguard Worker }
1438*ec779b8eSAndroid Build Coastguard Worker 
getImageEncodingQualityLevels(int cameraId) const1439*ec779b8eSAndroid Build Coastguard Worker Vector<int> MediaProfiles::getImageEncodingQualityLevels(int cameraId) const
1440*ec779b8eSAndroid Build Coastguard Worker {
1441*ec779b8eSAndroid Build Coastguard Worker     Vector<int> result;
1442*ec779b8eSAndroid Build Coastguard Worker     ImageEncodingQualityLevels *levels = findImageEncodingQualityLevels(cameraId);
1443*ec779b8eSAndroid Build Coastguard Worker     if (levels != NULL) {
1444*ec779b8eSAndroid Build Coastguard Worker         result = levels->mLevels;  // copy out
1445*ec779b8eSAndroid Build Coastguard Worker     }
1446*ec779b8eSAndroid Build Coastguard Worker     return result;
1447*ec779b8eSAndroid Build Coastguard Worker }
1448*ec779b8eSAndroid Build Coastguard Worker 
getStartTimeOffsetMs(int cameraId) const1449*ec779b8eSAndroid Build Coastguard Worker int MediaProfiles::getStartTimeOffsetMs(int cameraId) const {
1450*ec779b8eSAndroid Build Coastguard Worker     int offsetTimeMs = -1;
1451*ec779b8eSAndroid Build Coastguard Worker     ssize_t index = mStartTimeOffsets.indexOfKey(cameraId);
1452*ec779b8eSAndroid Build Coastguard Worker     if (index >= 0) {
1453*ec779b8eSAndroid Build Coastguard Worker         offsetTimeMs = mStartTimeOffsets.valueFor(cameraId);
1454*ec779b8eSAndroid Build Coastguard Worker     }
1455*ec779b8eSAndroid Build Coastguard Worker     ALOGV("offsetTime=%d ms and cameraId=%d", offsetTimeMs, cameraId);
1456*ec779b8eSAndroid Build Coastguard Worker     return offsetTimeMs;
1457*ec779b8eSAndroid Build Coastguard Worker }
1458*ec779b8eSAndroid Build Coastguard Worker 
~MediaProfiles()1459*ec779b8eSAndroid Build Coastguard Worker MediaProfiles::~MediaProfiles()
1460*ec779b8eSAndroid Build Coastguard Worker {
1461*ec779b8eSAndroid Build Coastguard Worker     CHECK("destructor should never be called" == 0);
1462*ec779b8eSAndroid Build Coastguard Worker #if 0
1463*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mAudioEncoders.size(); ++i) {
1464*ec779b8eSAndroid Build Coastguard Worker         delete mAudioEncoders[i];
1465*ec779b8eSAndroid Build Coastguard Worker     }
1466*ec779b8eSAndroid Build Coastguard Worker     mAudioEncoders.clear();
1467*ec779b8eSAndroid Build Coastguard Worker 
1468*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mVideoEncoders.size(); ++i) {
1469*ec779b8eSAndroid Build Coastguard Worker         delete mVideoEncoders[i];
1470*ec779b8eSAndroid Build Coastguard Worker     }
1471*ec779b8eSAndroid Build Coastguard Worker     mVideoEncoders.clear();
1472*ec779b8eSAndroid Build Coastguard Worker 
1473*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mVideoDecoders.size(); ++i) {
1474*ec779b8eSAndroid Build Coastguard Worker         delete mVideoDecoders[i];
1475*ec779b8eSAndroid Build Coastguard Worker     }
1476*ec779b8eSAndroid Build Coastguard Worker     mVideoDecoders.clear();
1477*ec779b8eSAndroid Build Coastguard Worker 
1478*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mAudioDecoders.size(); ++i) {
1479*ec779b8eSAndroid Build Coastguard Worker         delete mAudioDecoders[i];
1480*ec779b8eSAndroid Build Coastguard Worker     }
1481*ec779b8eSAndroid Build Coastguard Worker     mAudioDecoders.clear();
1482*ec779b8eSAndroid Build Coastguard Worker 
1483*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mCamcorderProfiles.size(); ++i) {
1484*ec779b8eSAndroid Build Coastguard Worker         delete mCamcorderProfiles[i];
1485*ec779b8eSAndroid Build Coastguard Worker     }
1486*ec779b8eSAndroid Build Coastguard Worker     mCamcorderProfiles.clear();
1487*ec779b8eSAndroid Build Coastguard Worker #endif
1488*ec779b8eSAndroid Build Coastguard Worker }
1489*ec779b8eSAndroid Build Coastguard Worker } // namespace android
1490