• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2010, The Android Open Source Project.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef ANDROID_MEDIAPROFILES_H
19 #define ANDROID_MEDIAPROFILES_H
20 
21 #include <utils/threads.h>
22 #include <media/mediarecorder.h>
23 
24 #include <vector>
25 
26 namespace android {
27 
28 enum camcorder_quality {
29     CAMCORDER_QUALITY_LIST_START = 0,
30     CAMCORDER_QUALITY_LOW  = 0,
31     CAMCORDER_QUALITY_HIGH = 1,
32     CAMCORDER_QUALITY_QCIF = 2,
33     CAMCORDER_QUALITY_CIF = 3,
34     CAMCORDER_QUALITY_480P = 4,
35     CAMCORDER_QUALITY_720P = 5,
36     CAMCORDER_QUALITY_1080P = 6,
37     CAMCORDER_QUALITY_QVGA = 7,
38     CAMCORDER_QUALITY_2160P = 8,
39     CAMCORDER_QUALITY_VGA = 9,
40     CAMCORDER_QUALITY_4KDCI = 10,
41     CAMCORDER_QUALITY_QHD = 11,
42     CAMCORDER_QUALITY_2K = 12,
43     CAMCORDER_QUALITY_8KUHD = 13,
44     CAMCORDER_QUALITY_LIST_END = 13,
45 
46     CAMCORDER_QUALITY_TIME_LAPSE_LIST_START = 1000,
47     CAMCORDER_QUALITY_TIME_LAPSE_LOW  = 1000,
48     CAMCORDER_QUALITY_TIME_LAPSE_HIGH = 1001,
49     CAMCORDER_QUALITY_TIME_LAPSE_QCIF = 1002,
50     CAMCORDER_QUALITY_TIME_LAPSE_CIF = 1003,
51     CAMCORDER_QUALITY_TIME_LAPSE_480P = 1004,
52     CAMCORDER_QUALITY_TIME_LAPSE_720P = 1005,
53     CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006,
54     CAMCORDER_QUALITY_TIME_LAPSE_QVGA = 1007,
55     CAMCORDER_QUALITY_TIME_LAPSE_2160P = 1008,
56     CAMCORDER_QUALITY_TIME_LAPSE_VGA = 1009,
57     CAMCORDER_QUALITY_TIME_LAPSE_4KDCI = 1010,
58     CAMCORDER_QUALITY_TIME_LAPSE_QHD = 1011,
59     CAMCORDER_QUALITY_TIME_LAPSE_2K = 1012,
60     CAMCORDER_QUALITY_TIME_LAPSE_8KUHD = 1013,
61     CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1013,
62 
63     CAMCORDER_QUALITY_HIGH_SPEED_LIST_START = 2000,
64     CAMCORDER_QUALITY_HIGH_SPEED_LOW  = 2000,
65     CAMCORDER_QUALITY_HIGH_SPEED_HIGH = 2001,
66     CAMCORDER_QUALITY_HIGH_SPEED_480P = 2002,
67     CAMCORDER_QUALITY_HIGH_SPEED_720P = 2003,
68     CAMCORDER_QUALITY_HIGH_SPEED_1080P = 2004,
69     CAMCORDER_QUALITY_HIGH_SPEED_2160P = 2005,
70     CAMCORDER_QUALITY_HIGH_SPEED_CIF = 2006,
71     CAMCORDER_QUALITY_HIGH_SPEED_VGA = 2007,
72     CAMCORDER_QUALITY_HIGH_SPEED_4KDCI = 2008,
73     CAMCORDER_QUALITY_HIGH_SPEED_LIST_END = 2008,
74 };
75 
76 enum video_decoder {
77     VIDEO_DECODER_WMV,
78 };
79 
80 enum audio_decoder {
81     AUDIO_DECODER_WMA,
82 };
83 
84 
85 class MediaProfiles
86 {
87 public:
88 
89     /**
90      * Returns the singleton instance for subsequence queries or NULL if error.
91      *
92      * If property media.settings.xml is set, getInstance() will attempt to read
93      * from file path in media.settings.xml. Otherwise, getInstance() will
94      * search through the list of preset XML file paths.
95      *
96      * If the search is unsuccessful, the default instance will be created
97      * instead.
98      *
99      * TODO: After validation is added, getInstance() should handle validation
100      * failure properly.
101      */
102     static MediaProfiles* getInstance();
103 
104     /**
105      * Configuration for a video encoder.
106      */
107     struct VideoCodec {
108     public:
109         /**
110          * Constructs a video encoder configuration.
111          *
112          * @param codec codec type
113          * @param bitrate bitrate in bps
114          * @param frameWidth frame width in pixels
115          * @param frameHeight frame height in pixels
116          * @param frameRate frame rate in fps
117          * @param profile codec profile (for MediaCodec) or -1 for none
118          */
119         VideoCodec(video_encoder codec, int bitrate, int frameWidth, int frameHeight, int frameRate,
120                    int profile = -1)
mCodecVideoCodec121             : mCodec(codec),
122               mBitRate(bitrate),
123               mFrameWidth(frameWidth),
124               mFrameHeight(frameHeight),
125               mFrameRate(frameRate),
126               mProfile(profile) {
127         }
128 
129         VideoCodec(const VideoCodec&) = default;
130 
~VideoCodecVideoCodec131         ~VideoCodec() {}
132 
133         /** Returns the codec type. */
getCodecVideoCodec134         video_encoder getCodec() const {
135             return mCodec;
136         }
137 
138         /** Returns the bitrate in bps. */
getBitrateVideoCodec139         int getBitrate() const {
140             return mBitRate;
141         }
142 
143         /** Returns the frame width in pixels. */
getFrameWidthVideoCodec144         int getFrameWidth() const {
145             return mFrameWidth;
146         }
147 
148         /** Returns the frame height in pixels. */
getFrameHeightVideoCodec149         int getFrameHeight() const {
150             return mFrameHeight;
151         }
152 
153         /** Returns the frame rate in fps. */
getFrameRateVideoCodec154         int getFrameRate() const {
155             return mFrameRate;
156         }
157 
158         /** Returns the codec profile (or -1 for no profile). */
getProfileVideoCodec159         int getProfile() const {
160             return mProfile;
161         }
162 
163     private:
164         video_encoder mCodec;
165         int mBitRate;
166         int mFrameWidth;
167         int mFrameHeight;
168         int mFrameRate;
169         int mProfile;
170         friend class MediaProfiles;
171     };
172 
173     /**
174      * Configuration for an audio encoder.
175      */
176     struct AudioCodec {
177     public:
178         /**
179          * Constructs an audio encoder configuration.
180          *
181          * @param codec codec type
182          * @param bitrate bitrate in bps
183          * @param sampleRate sample rate in Hz
184          * @param channels number of channels
185          * @param profile codec profile (for MediaCodec) or -1 for none
186          */
187         AudioCodec(audio_encoder codec, int bitrate, int sampleRate, int channels, int profile = -1)
mCodecAudioCodec188             : mCodec(codec),
189               mBitRate(bitrate),
190               mSampleRate(sampleRate),
191               mChannels(channels),
192               mProfile(profile) {
193         }
194 
195         AudioCodec(const AudioCodec&) = default;
196 
~AudioCodecAudioCodec197         ~AudioCodec() {}
198 
199         /** Returns the codec type. */
getCodecAudioCodec200         audio_encoder getCodec() const {
201             return mCodec;
202         }
203 
204         /** Returns the bitrate in bps. */
getBitrateAudioCodec205         int getBitrate() const {
206             return mBitRate;
207         }
208 
209         /** Returns the sample rate in Hz. */
getSampleRateAudioCodec210         int getSampleRate() const {
211             return mSampleRate;
212         }
213 
214         /** Returns the number of channels. */
getChannelsAudioCodec215         int getChannels() const {
216             return mChannels;
217         }
218 
219         /** Returns the codec profile (or -1 for no profile). */
getProfileAudioCodec220         int getProfile() const {
221             return mProfile;
222         }
223 
224     private:
225         audio_encoder mCodec;
226         int mBitRate;
227         int mSampleRate;
228         int mChannels;
229         int mProfile;
230         friend class MediaProfiles;
231     };
232 
233     /**
234      * Configuration for a camcorder profile/encoder profiles object.
235      */
236     struct CamcorderProfile {
237         /**
238          *  Returns on ordered list of the video codec configurations in
239          *  decreasing preference. The returned object is only valid
240          *  during the lifetime of this object.
241          */
242         std::vector<const VideoCodec *> getVideoCodecs() const;
243 
244         /**
245          *  Returns on ordered list of the audio codec configurations in
246          *  decreasing preference. The returned object is only valid
247          *  during the lifetime of this object.
248          */
249         std::vector<const AudioCodec *> getAudioCodecs() const;
250 
251         /** Returns the default duration in seconds. */
getDurationCamcorderProfile252         int getDuration() const {
253             return mDuration;
254         }
255 
256         /** Returns the preferred file format. */
getFileFormatCamcorderProfile257         int getFileFormat() const {
258             return mFileFormat;
259         }
260 
261         CamcorderProfile(const CamcorderProfile& copy) = default;
262 
263         ~CamcorderProfile() = default;
264 
265     private:
266         /**
267          * Constructs an empty object with no audio/video profiles.
268          */
CamcorderProfileCamcorderProfile269         CamcorderProfile()
270             : mCameraId(0),
271               mFileFormat(OUTPUT_FORMAT_THREE_GPP),
272               mQuality(CAMCORDER_QUALITY_HIGH),
273               mDuration(0) {}
274 
275         int mCameraId;
276         output_format mFileFormat;
277         camcorder_quality mQuality;
278         int mDuration;
279         std::vector<VideoCodec> mVideoCodecs;
280         std::vector<AudioCodec> mAudioCodecs;
281         friend class MediaProfiles;
282     };
283 
284     /**
285      * Returns the CamcorderProfile object for the given camera at
286      * the given quality level, or null if it does not exist.
287      */
288     const CamcorderProfile *getCamcorderProfile(
289             int cameraId, camcorder_quality quality) const;
290 
291     /**
292      * Returns the value for the given param name for the given camera at
293      * the given quality level, or -1 if error.
294      *
295      * Supported param name are:
296      * duration - the recording duration.
297      * file.format - output file format. see mediarecorder.h for details
298      * vid.codec - video encoder. see mediarecorder.h for details.
299      * aud.codec - audio encoder. see mediarecorder.h for details.
300      * vid.width - video frame width
301      * vid.height - video frame height
302      * vid.fps - video frame rate
303      * vid.bps - video bit rate
304      * aud.bps - audio bit rate
305      * aud.hz - audio sample rate
306      * aud.ch - number of audio channels
307      */
308     int getCamcorderProfileParamByName(const char *name, int cameraId,
309                                        camcorder_quality quality) const;
310 
311     /**
312      * Returns true if a profile for the given camera at the given quality exists,
313      * or false if not.
314      */
315     bool hasCamcorderProfile(int cameraId, camcorder_quality quality) const;
316 
317     /**
318      * Returns the output file formats supported.
319      */
320     Vector<output_format> getOutputFileFormats() const;
321 
322     /**
323      * Returns the video encoders supported.
324      */
325     Vector<video_encoder> getVideoEncoders() const;
326 
327     /**
328      * Returns the value for the given param name for the given video encoder
329      * returned from getVideoEncoderByIndex or -1 if error.
330      *
331      * Supported param name are:
332      * enc.vid.width.min - min video frame width
333      * enc.vid.width.max - max video frame width
334      * enc.vid.height.min - min video frame height
335      * enc.vid.height.max - max video frame height
336      * enc.vid.bps.min - min bit rate in bits per second
337      * enc.vid.bps.max - max bit rate in bits per second
338      * enc.vid.fps.min - min frame rate in frames per second
339      * enc.vid.fps.max - max frame rate in frames per second
340      */
341     int getVideoEncoderParamByName(const char *name, video_encoder codec) const;
342 
343     /**
344      * Returns the audio encoders supported.
345      */
346     Vector<audio_encoder> getAudioEncoders() const;
347 
348     /**
349      * Returns the value for the given param name for the given audio encoder
350      * returned from getAudioEncoderByIndex or -1 if error.
351      *
352      * Supported param name are:
353      * enc.aud.ch.min - min number of channels
354      * enc.aud.ch.max - max number of channels
355      * enc.aud.bps.min - min bit rate in bits per second
356      * enc.aud.bps.max - max bit rate in bits per second
357      * enc.aud.hz.min - min sample rate in samples per second
358      * enc.aud.hz.max - max sample rate in samples per second
359      */
360     int getAudioEncoderParamByName(const char *name, audio_encoder codec) const;
361 
362     /**
363       * Returns the video decoders supported.
364       */
365     Vector<video_decoder> getVideoDecoders() const;
366 
367      /**
368       * Returns the audio decoders supported.
369       */
370     Vector<audio_decoder> getAudioDecoders() const;
371 
372     /**
373      * Returns the number of image encoding quality levels supported.
374      */
375     Vector<int> getImageEncodingQualityLevels(int cameraId) const;
376 
377     /**
378      * Returns the start time offset (in ms) for the given camera Id.
379      * If the given camera Id does not exist, -1 will be returned.
380      */
381     int getStartTimeOffsetMs(int cameraId) const;
382 
383 private:
384     enum {
385         // Camcorder profiles (high/low) and timelapse profiles (high/low)
386         kNumRequiredProfiles = 4,
387     };
388 
389     MediaProfiles& operator=(const MediaProfiles&);  // Don't call me
390     MediaProfiles(const MediaProfiles&);             // Don't call me
MediaProfiles()391     MediaProfiles() {}                               // Dummy default constructor
392     ~MediaProfiles();                                // Don't delete me
393 
394     struct VideoEncoderCap {
395         // Ugly constructor
VideoEncoderCapVideoEncoderCap396         VideoEncoderCap(video_encoder codec,
397                         int minBitRate, int maxBitRate,
398                         int minFrameWidth, int maxFrameWidth,
399                         int minFrameHeight, int maxFrameHeight,
400                         int minFrameRate, int maxFrameRate)
401             : mCodec(codec),
402               mMinBitRate(minBitRate), mMaxBitRate(maxBitRate),
403               mMinFrameWidth(minFrameWidth), mMaxFrameWidth(maxFrameWidth),
404               mMinFrameHeight(minFrameHeight), mMaxFrameHeight(maxFrameHeight),
405               mMinFrameRate(minFrameRate), mMaxFrameRate(maxFrameRate) {}
406 
~VideoEncoderCapVideoEncoderCap407          ~VideoEncoderCap() {}
408 
409         video_encoder mCodec;
410         int mMinBitRate, mMaxBitRate;
411         int mMinFrameWidth, mMaxFrameWidth;
412         int mMinFrameHeight, mMaxFrameHeight;
413         int mMinFrameRate, mMaxFrameRate;
414     };
415 
416     struct AudioEncoderCap {
417         // Ugly constructor
AudioEncoderCapAudioEncoderCap418         AudioEncoderCap(audio_encoder codec,
419                         int minBitRate, int maxBitRate,
420                         int minSampleRate, int maxSampleRate,
421                         int minChannels, int maxChannels)
422             : mCodec(codec),
423               mMinBitRate(minBitRate), mMaxBitRate(maxBitRate),
424               mMinSampleRate(minSampleRate), mMaxSampleRate(maxSampleRate),
425               mMinChannels(minChannels), mMaxChannels(maxChannels) {}
426 
~AudioEncoderCapAudioEncoderCap427         ~AudioEncoderCap() {}
428 
429         audio_encoder mCodec;
430         int mMinBitRate, mMaxBitRate;
431         int mMinSampleRate, mMaxSampleRate;
432         int mMinChannels, mMaxChannels;
433     };
434 
435     struct VideoDecoderCap {
VideoDecoderCapVideoDecoderCap436         VideoDecoderCap(video_decoder codec): mCodec(codec) {}
~VideoDecoderCapVideoDecoderCap437         ~VideoDecoderCap() {}
438 
439         video_decoder mCodec;
440     };
441 
442     struct AudioDecoderCap {
AudioDecoderCapAudioDecoderCap443         AudioDecoderCap(audio_decoder codec): mCodec(codec) {}
~AudioDecoderCapAudioDecoderCap444         ~AudioDecoderCap() {}
445 
446         audio_decoder mCodec;
447     };
448 
449     struct NameToTagMap {
450         const char* name;
451         int tag;
452     };
453 
454     struct ImageEncodingQualityLevels {
455         int mCameraId;
456         Vector<int> mLevels;
457     };
458 
459     int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const;
460     void initRequiredProfileRefs(const Vector<int>& cameraIds);
461     int getRequiredProfileRefIndex(int cameraId);
462 
463     // Debug
464     static void logVideoCodec(const VideoCodec& codec);
465     static void logAudioCodec(const AudioCodec& codec);
466     static void logVideoEncoderCap(const VideoEncoderCap& cap);
467     static void logAudioEncoderCap(const AudioEncoderCap& cap);
468     static void logVideoDecoderCap(const VideoDecoderCap& cap);
469     static void logAudioDecoderCap(const AudioDecoderCap& cap);
470 
471     // Returns true if xmlFile exists.
472     // TODO: Add runtime validation.
473     static bool checkXmlFile(const char* xmlFile);
474 
475     // If the xml configuration file does exist, use the settings
476     // from the xml
477     static MediaProfiles* createInstanceFromXmlFile(const char *xml);
478     static output_format createEncoderOutputFileFormat(const char **atts, size_t natts);
479     static void createVideoCodec(const char **atts, size_t natts, MediaProfiles *profiles);
480     static void createAudioCodec(const char **atts, size_t natts, MediaProfiles *profiles);
481     static AudioDecoderCap* createAudioDecoderCap(const char **atts, size_t natts);
482     static VideoDecoderCap* createVideoDecoderCap(const char **atts, size_t natts);
483     static VideoEncoderCap* createVideoEncoderCap(const char **atts, size_t natts);
484     static AudioEncoderCap* createAudioEncoderCap(const char **atts, size_t natts);
485 
486     static CamcorderProfile* createCamcorderProfile(
487                 int cameraId, const char **atts, size_t natts, Vector<int>& cameraIds);
488 
489     static int getCameraId(const char **atts, size_t natts);
490 
491     void addStartTimeOffset(int cameraId, const char **atts, size_t natts);
492 
493     ImageEncodingQualityLevels* findImageEncodingQualityLevels(int cameraId) const;
494     void addImageEncodingQualityLevel(int cameraId, const char** atts, size_t natts);
495 
496     // Customized element tag handler for parsing the xml configuration file.
497     static void startElementHandler(void *userData, const char *name, const char **atts);
498 
499     // If the xml configuration file does not exist, use hard-coded values
500     static MediaProfiles* createDefaultInstance();
501 
502     static CamcorderProfile *createDefaultCamcorderQcifProfile(camcorder_quality quality);
503     static CamcorderProfile *createDefaultCamcorderCifProfile(camcorder_quality quality);
504     static void createDefaultCamcorderLowProfiles(
505             MediaProfiles::CamcorderProfile **lowProfile,
506             MediaProfiles::CamcorderProfile **lowSpecificProfile);
507     static void createDefaultCamcorderHighProfiles(
508             MediaProfiles::CamcorderProfile **highProfile,
509             MediaProfiles::CamcorderProfile **highSpecificProfile);
510 
511     static CamcorderProfile *createDefaultCamcorderTimeLapseQcifProfile(camcorder_quality quality);
512     static CamcorderProfile *createDefaultCamcorderTimeLapse480pProfile(camcorder_quality quality);
513     static void createDefaultCamcorderTimeLapseLowProfiles(
514             MediaProfiles::CamcorderProfile **lowTimeLapseProfile,
515             MediaProfiles::CamcorderProfile **lowSpecificTimeLapseProfile);
516     static void createDefaultCamcorderTimeLapseHighProfiles(
517             MediaProfiles::CamcorderProfile **highTimeLapseProfile,
518             MediaProfiles::CamcorderProfile **highSpecificTimeLapseProfile);
519 
520     static void createDefaultCamcorderProfiles(MediaProfiles *profiles);
521     static void createDefaultVideoEncoders(MediaProfiles *profiles);
522     static void createDefaultAudioEncoders(MediaProfiles *profiles);
523     static void createDefaultVideoDecoders(MediaProfiles *profiles);
524     static void createDefaultAudioDecoders(MediaProfiles *profiles);
525     static void createDefaultEncoderOutputFileFormats(MediaProfiles *profiles);
526     static void createDefaultImageEncodingQualityLevels(MediaProfiles *profiles);
527     static void createDefaultImageDecodingMaxMemory(MediaProfiles *profiles);
528 
529     static VideoEncoderCap* createDefaultH263VideoEncoderCap();
530     static VideoEncoderCap* createDefaultM4vVideoEncoderCap();
531     static AudioEncoderCap* createDefaultAmrNBEncoderCap();
532 
533     static int findTagForName(const NameToTagMap *map, size_t nMappings, const char *name);
534 
535     /**
536      * Check on existing profiles with the following criteria:
537      * 1. Low quality profile must have the lowest video
538      *    resolution product (width x height)
539      * 2. High quality profile must have the highest video
540      *    resolution product (width x height)
541      *
542      * and add required low/high quality camcorder/timelapse
543      * profiles if they are not found. This allows to remove
544      * duplicate profile definitions in the media_profiles.xml
545      * file.
546      */
547     void checkAndAddRequiredProfilesIfNecessary();
548 
549 
550     // Mappings from name (for instance, codec name) to enum value
551     static const NameToTagMap sVideoEncoderNameMap[];
552     static const NameToTagMap sAudioEncoderNameMap[];
553     static const NameToTagMap sFileFormatMap[];
554     static const NameToTagMap sVideoDecoderNameMap[];
555     static const NameToTagMap sAudioDecoderNameMap[];
556     static const NameToTagMap sCamcorderQualityNameMap[];
557 
558     static bool sIsInitialized;
559     static MediaProfiles *sInstance;
560     static Mutex sLock;
561     int mCurrentCameraId;
562 
563     Vector<CamcorderProfile*> mCamcorderProfiles;
564     Vector<AudioEncoderCap*>  mAudioEncoders;
565     Vector<VideoEncoderCap*>  mVideoEncoders;
566     Vector<AudioDecoderCap*>  mAudioDecoders;
567     Vector<VideoDecoderCap*>  mVideoDecoders;
568     Vector<output_format>     mEncoderOutputFileFormats;
569     Vector<ImageEncodingQualityLevels *>  mImageEncodingQualityLevels;
570     KeyedVector<int, int> mStartTimeOffsets;
571 
572     typedef struct {
573         bool mHasRefProfile;      // Refers to an existing profile
574         int  mRefProfileIndex;    // Reference profile index
575         int  mResolutionProduct;  // width x height
576     } RequiredProfileRefInfo;     // Required low and high profiles
577 
578     typedef struct {
579         RequiredProfileRefInfo mRefs[kNumRequiredProfiles];
580         int mCameraId;
581     } RequiredProfiles;
582 
583     RequiredProfiles *mRequiredProfileRefs;
584     Vector<int>              mCameraIds;
585 };
586 
587 }; // namespace android
588 
589 #endif // ANDROID_MEDIAPROFILES_H
590