• 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 namespace android {
25 
26 enum camcorder_quality {
27     CAMCORDER_QUALITY_LIST_START = 0,
28     CAMCORDER_QUALITY_LOW  = 0,
29     CAMCORDER_QUALITY_HIGH = 1,
30     CAMCORDER_QUALITY_QCIF = 2,
31     CAMCORDER_QUALITY_CIF = 3,
32     CAMCORDER_QUALITY_480P = 4,
33     CAMCORDER_QUALITY_720P = 5,
34     CAMCORDER_QUALITY_1080P = 6,
35     CAMCORDER_QUALITY_QVGA = 7,
36     CAMCORDER_QUALITY_2160P = 8,
37     CAMCORDER_QUALITY_LIST_END = 8,
38 
39     CAMCORDER_QUALITY_TIME_LAPSE_LIST_START = 1000,
40     CAMCORDER_QUALITY_TIME_LAPSE_LOW  = 1000,
41     CAMCORDER_QUALITY_TIME_LAPSE_HIGH = 1001,
42     CAMCORDER_QUALITY_TIME_LAPSE_QCIF = 1002,
43     CAMCORDER_QUALITY_TIME_LAPSE_CIF = 1003,
44     CAMCORDER_QUALITY_TIME_LAPSE_480P = 1004,
45     CAMCORDER_QUALITY_TIME_LAPSE_720P = 1005,
46     CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006,
47     CAMCORDER_QUALITY_TIME_LAPSE_QVGA = 1007,
48     CAMCORDER_QUALITY_TIME_LAPSE_2160P = 1008,
49     CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1008,
50 
51     CAMCORDER_QUALITY_HIGH_SPEED_LIST_START = 2000,
52     CAMCORDER_QUALITY_HIGH_SPEED_LOW  = 2000,
53     CAMCORDER_QUALITY_HIGH_SPEED_HIGH = 2001,
54     CAMCORDER_QUALITY_HIGH_SPEED_480P = 2002,
55     CAMCORDER_QUALITY_HIGH_SPEED_720P = 2003,
56     CAMCORDER_QUALITY_HIGH_SPEED_1080P = 2004,
57     CAMCORDER_QUALITY_HIGH_SPEED_2160P = 2005,
58     CAMCORDER_QUALITY_HIGH_SPEED_LIST_END = 2005,
59 };
60 
61 /**
62  * Set CIF as default maximum import and export resolution of video editor.
63  * The maximum import and export resolutions are platform specific,
64  * which should be defined in media_profiles.xml.
65  * Set default maximum prefetch YUV frames to 6, which means video editor can
66  * queue up to 6 YUV frames in the video encoder source.
67  * This value is used to limit the amount of memory used by video editor
68  * engine when the encoder consumes YUV frames at a lower speed
69  * than video editor engine produces.
70  */
71 enum videoeditor_capability {
72     VIDEOEDITOR_DEFAULT_MAX_INPUT_FRAME_WIDTH = 352,
73     VIDEOEDITOR_DEFUALT_MAX_INPUT_FRAME_HEIGHT = 288,
74     VIDEOEDITOR_DEFAULT_MAX_OUTPUT_FRAME_WIDTH = 352,
75     VIDEOEDITOR_DEFUALT_MAX_OUTPUT_FRAME_HEIGHT = 288,
76     VIDEOEDITOR_DEFAULT_MAX_PREFETCH_YUV_FRAMES = 6
77 };
78 
79 enum video_decoder {
80     VIDEO_DECODER_WMV,
81 };
82 
83 enum audio_decoder {
84     AUDIO_DECODER_WMA,
85 };
86 
87 
88 class MediaProfiles
89 {
90 public:
91 
92     /**
93      * Returns the singleton instance for subsequence queries.
94      * or NULL if error.
95      */
96     static MediaProfiles* getInstance();
97 
98     /**
99      * Returns the value for the given param name for the given camera at
100      * the given quality level, or -1 if error.
101      *
102      * Supported param name are:
103      * duration - the recording duration.
104      * file.format - output file format. see mediarecorder.h for details
105      * vid.codec - video encoder. see mediarecorder.h for details.
106      * aud.codec - audio encoder. see mediarecorder.h for details.
107      * vid.width - video frame width
108      * vid.height - video frame height
109      * vid.fps - video frame rate
110      * vid.bps - video bit rate
111      * aud.bps - audio bit rate
112      * aud.hz - audio sample rate
113      * aud.ch - number of audio channels
114      */
115     int getCamcorderProfileParamByName(const char *name, int cameraId,
116                                        camcorder_quality quality) const;
117 
118     /**
119      * Returns true if a profile for the given camera at the given quality exists,
120      * or false if not.
121      */
122     bool hasCamcorderProfile(int cameraId, camcorder_quality quality) const;
123 
124     /**
125      * Returns the output file formats supported.
126      */
127     Vector<output_format> getOutputFileFormats() const;
128 
129     /**
130      * Returns the video encoders supported.
131      */
132     Vector<video_encoder> getVideoEncoders() const;
133 
134     /**
135      * Returns the value for the given param name for the given video encoder
136      * returned from getVideoEncoderByIndex or -1 if error.
137      *
138      * Supported param name are:
139      * enc.vid.width.min - min video frame width
140      * enc.vid.width.max - max video frame width
141      * enc.vid.height.min - min video frame height
142      * enc.vid.height.max - max video frame height
143      * enc.vid.bps.min - min bit rate in bits per second
144      * enc.vid.bps.max - max bit rate in bits per second
145      * enc.vid.fps.min - min frame rate in frames per second
146      * enc.vid.fps.max - max frame rate in frames per second
147      */
148     int getVideoEncoderParamByName(const char *name, video_encoder codec) const;
149 
150     /**
151      * Returns the value for the given param name for the video editor cap
152      * param or -1 if error.
153      * Supported param name are:
154      * videoeditor.input.width.max - max input video frame width
155      * videoeditor.input.height.max - max input video frame height
156      * videoeditor.output.width.max - max output video frame width
157      * videoeditor.output.height.max - max output video frame height
158      * maxPrefetchYUVFrames - max prefetch YUV frames in video editor engine. This value is used
159      * to limit the memory consumption.
160      */
161     int getVideoEditorCapParamByName(const char *name) const;
162 
163     /**
164      * Returns the value for the given param name for the video editor export codec format
165      * param or -1 if error.
166      * Supported param name are:
167      * videoeditor.export.profile - export video profile
168      * videoeditor.export.level - export video level
169      * Supported param codec are:
170      * 1 for h263
171      * 2 for h264
172      * 3 for mpeg4
173      */
174     int getVideoEditorExportParamByName(const char *name, int codec) const;
175 
176     /**
177      * Returns the audio encoders supported.
178      */
179     Vector<audio_encoder> getAudioEncoders() const;
180 
181     /**
182      * Returns the value for the given param name for the given audio encoder
183      * returned from getAudioEncoderByIndex or -1 if error.
184      *
185      * Supported param name are:
186      * enc.aud.ch.min - min number of channels
187      * enc.aud.ch.max - max number of channels
188      * enc.aud.bps.min - min bit rate in bits per second
189      * enc.aud.bps.max - max bit rate in bits per second
190      * enc.aud.hz.min - min sample rate in samples per second
191      * enc.aud.hz.max - max sample rate in samples per second
192      */
193     int getAudioEncoderParamByName(const char *name, audio_encoder codec) const;
194 
195     /**
196       * Returns the video decoders supported.
197       */
198     Vector<video_decoder> getVideoDecoders() const;
199 
200      /**
201       * Returns the audio decoders supported.
202       */
203     Vector<audio_decoder> getAudioDecoders() const;
204 
205     /**
206      * Returns the number of image encoding quality levels supported.
207      */
208     Vector<int> getImageEncodingQualityLevels(int cameraId) const;
209 
210     /**
211      * Returns the start time offset (in ms) for the given camera Id.
212      * If the given camera Id does not exist, -1 will be returned.
213      */
214     int getStartTimeOffsetMs(int cameraId) const;
215 
216 private:
217     enum {
218         // Camcorder profiles (high/low) and timelapse profiles (high/low)
219         kNumRequiredProfiles = 4,
220     };
221 
222     MediaProfiles& operator=(const MediaProfiles&);  // Don't call me
223     MediaProfiles(const MediaProfiles&);             // Don't call me
MediaProfiles()224     MediaProfiles() { mVideoEditorCap = NULL; }        // Dummy default constructor
225     ~MediaProfiles();                                // Don't delete me
226 
227     struct VideoCodec {
VideoCodecVideoCodec228         VideoCodec(video_encoder codec, int bitRate, int frameWidth, int frameHeight, int frameRate)
229             : mCodec(codec),
230               mBitRate(bitRate),
231               mFrameWidth(frameWidth),
232               mFrameHeight(frameHeight),
233               mFrameRate(frameRate) {}
234 
VideoCodecVideoCodec235         VideoCodec(const VideoCodec& copy) {
236             mCodec = copy.mCodec;
237             mBitRate = copy.mBitRate;
238             mFrameWidth = copy.mFrameWidth;
239             mFrameHeight = copy.mFrameHeight;
240             mFrameRate = copy.mFrameRate;
241         }
242 
~VideoCodecVideoCodec243         ~VideoCodec() {}
244 
245         video_encoder mCodec;
246         int mBitRate;
247         int mFrameWidth;
248         int mFrameHeight;
249         int mFrameRate;
250     };
251 
252     struct AudioCodec {
AudioCodecAudioCodec253         AudioCodec(audio_encoder codec, int bitRate, int sampleRate, int channels)
254             : mCodec(codec),
255               mBitRate(bitRate),
256               mSampleRate(sampleRate),
257               mChannels(channels) {}
258 
AudioCodecAudioCodec259         AudioCodec(const AudioCodec& copy) {
260             mCodec = copy.mCodec;
261             mBitRate = copy.mBitRate;
262             mSampleRate = copy.mSampleRate;
263             mChannels = copy.mChannels;
264         }
265 
~AudioCodecAudioCodec266         ~AudioCodec() {}
267 
268         audio_encoder mCodec;
269         int mBitRate;
270         int mSampleRate;
271         int mChannels;
272     };
273 
274     struct CamcorderProfile {
CamcorderProfileCamcorderProfile275         CamcorderProfile()
276             : mCameraId(0),
277               mFileFormat(OUTPUT_FORMAT_THREE_GPP),
278               mQuality(CAMCORDER_QUALITY_HIGH),
279               mDuration(0),
280               mVideoCodec(0),
281               mAudioCodec(0) {}
282 
CamcorderProfileCamcorderProfile283         CamcorderProfile(const CamcorderProfile& copy) {
284             mCameraId = copy.mCameraId;
285             mFileFormat = copy.mFileFormat;
286             mQuality = copy.mQuality;
287             mDuration = copy.mDuration;
288             mVideoCodec = new VideoCodec(*copy.mVideoCodec);
289             mAudioCodec = new AudioCodec(*copy.mAudioCodec);
290         }
291 
~CamcorderProfileCamcorderProfile292         ~CamcorderProfile() {
293             delete mVideoCodec;
294             delete mAudioCodec;
295         }
296 
297         int mCameraId;
298         output_format mFileFormat;
299         camcorder_quality mQuality;
300         int mDuration;
301         VideoCodec *mVideoCodec;
302         AudioCodec *mAudioCodec;
303     };
304 
305     struct VideoEncoderCap {
306         // Ugly constructor
VideoEncoderCapVideoEncoderCap307         VideoEncoderCap(video_encoder codec,
308                         int minBitRate, int maxBitRate,
309                         int minFrameWidth, int maxFrameWidth,
310                         int minFrameHeight, int maxFrameHeight,
311                         int minFrameRate, int maxFrameRate)
312             : mCodec(codec),
313               mMinBitRate(minBitRate), mMaxBitRate(maxBitRate),
314               mMinFrameWidth(minFrameWidth), mMaxFrameWidth(maxFrameWidth),
315               mMinFrameHeight(minFrameHeight), mMaxFrameHeight(maxFrameHeight),
316               mMinFrameRate(minFrameRate), mMaxFrameRate(maxFrameRate) {}
317 
~VideoEncoderCapVideoEncoderCap318          ~VideoEncoderCap() {}
319 
320         video_encoder mCodec;
321         int mMinBitRate, mMaxBitRate;
322         int mMinFrameWidth, mMaxFrameWidth;
323         int mMinFrameHeight, mMaxFrameHeight;
324         int mMinFrameRate, mMaxFrameRate;
325     };
326 
327     struct AudioEncoderCap {
328         // Ugly constructor
AudioEncoderCapAudioEncoderCap329         AudioEncoderCap(audio_encoder codec,
330                         int minBitRate, int maxBitRate,
331                         int minSampleRate, int maxSampleRate,
332                         int minChannels, int maxChannels)
333             : mCodec(codec),
334               mMinBitRate(minBitRate), mMaxBitRate(maxBitRate),
335               mMinSampleRate(minSampleRate), mMaxSampleRate(maxSampleRate),
336               mMinChannels(minChannels), mMaxChannels(maxChannels) {}
337 
~AudioEncoderCapAudioEncoderCap338         ~AudioEncoderCap() {}
339 
340         audio_encoder mCodec;
341         int mMinBitRate, mMaxBitRate;
342         int mMinSampleRate, mMaxSampleRate;
343         int mMinChannels, mMaxChannels;
344     };
345 
346     struct VideoDecoderCap {
VideoDecoderCapVideoDecoderCap347         VideoDecoderCap(video_decoder codec): mCodec(codec) {}
~VideoDecoderCapVideoDecoderCap348         ~VideoDecoderCap() {}
349 
350         video_decoder mCodec;
351     };
352 
353     struct AudioDecoderCap {
AudioDecoderCapAudioDecoderCap354         AudioDecoderCap(audio_decoder codec): mCodec(codec) {}
~AudioDecoderCapAudioDecoderCap355         ~AudioDecoderCap() {}
356 
357         audio_decoder mCodec;
358     };
359 
360     struct NameToTagMap {
361         const char* name;
362         int tag;
363     };
364 
365     struct ImageEncodingQualityLevels {
366         int mCameraId;
367         Vector<int> mLevels;
368     };
369     struct ExportVideoProfile {
ExportVideoProfileExportVideoProfile370         ExportVideoProfile(int codec, int profile, int level)
371             :mCodec(codec),mProfile(profile),mLevel(level) {}
~ExportVideoProfileExportVideoProfile372         ~ExportVideoProfile() {}
373         int mCodec;
374         int mProfile;
375         int mLevel;
376     };
377     struct VideoEditorCap {
VideoEditorCapVideoEditorCap378         VideoEditorCap(int inFrameWidth, int inFrameHeight,
379             int outFrameWidth, int outFrameHeight, int frames)
380             : mMaxInputFrameWidth(inFrameWidth),
381               mMaxInputFrameHeight(inFrameHeight),
382               mMaxOutputFrameWidth(outFrameWidth),
383               mMaxOutputFrameHeight(outFrameHeight),
384               mMaxPrefetchYUVFrames(frames) {}
385 
~VideoEditorCapVideoEditorCap386         ~VideoEditorCap() {}
387 
388         int mMaxInputFrameWidth;
389         int mMaxInputFrameHeight;
390         int mMaxOutputFrameWidth;
391         int mMaxOutputFrameHeight;
392         int mMaxPrefetchYUVFrames;
393     };
394 
395     int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const;
396     void initRequiredProfileRefs(const Vector<int>& cameraIds);
397     int getRequiredProfileRefIndex(int cameraId);
398 
399     // Debug
400     static void logVideoCodec(const VideoCodec& codec);
401     static void logAudioCodec(const AudioCodec& codec);
402     static void logVideoEncoderCap(const VideoEncoderCap& cap);
403     static void logAudioEncoderCap(const AudioEncoderCap& cap);
404     static void logVideoDecoderCap(const VideoDecoderCap& cap);
405     static void logAudioDecoderCap(const AudioDecoderCap& cap);
406     static void logVideoEditorCap(const VideoEditorCap& cap);
407 
408     // If the xml configuration file does exist, use the settings
409     // from the xml
410     static MediaProfiles* createInstanceFromXmlFile(const char *xml);
411     static output_format createEncoderOutputFileFormat(const char **atts);
412     static VideoCodec* createVideoCodec(const char **atts, MediaProfiles *profiles);
413     static AudioCodec* createAudioCodec(const char **atts, MediaProfiles *profiles);
414     static AudioDecoderCap* createAudioDecoderCap(const char **atts);
415     static VideoDecoderCap* createVideoDecoderCap(const char **atts);
416     static VideoEncoderCap* createVideoEncoderCap(const char **atts);
417     static AudioEncoderCap* createAudioEncoderCap(const char **atts);
418     static VideoEditorCap* createVideoEditorCap(
419                 const char **atts, MediaProfiles *profiles);
420     static ExportVideoProfile* createExportVideoProfile(const char **atts);
421 
422     static CamcorderProfile* createCamcorderProfile(
423                 int cameraId, const char **atts, Vector<int>& cameraIds);
424 
425     static int getCameraId(const char **atts);
426 
427     void addStartTimeOffset(int cameraId, const char **atts);
428 
429     ImageEncodingQualityLevels* findImageEncodingQualityLevels(int cameraId) const;
430     void addImageEncodingQualityLevel(int cameraId, const char** atts);
431 
432     // Customized element tag handler for parsing the xml configuration file.
433     static void startElementHandler(void *userData, const char *name, const char **atts);
434 
435     // If the xml configuration file does not exist, use hard-coded values
436     static MediaProfiles* createDefaultInstance();
437 
438     static CamcorderProfile *createDefaultCamcorderQcifProfile(camcorder_quality quality);
439     static CamcorderProfile *createDefaultCamcorderCifProfile(camcorder_quality quality);
440     static void createDefaultCamcorderLowProfiles(
441             MediaProfiles::CamcorderProfile **lowProfile,
442             MediaProfiles::CamcorderProfile **lowSpecificProfile);
443     static void createDefaultCamcorderHighProfiles(
444             MediaProfiles::CamcorderProfile **highProfile,
445             MediaProfiles::CamcorderProfile **highSpecificProfile);
446 
447     static CamcorderProfile *createDefaultCamcorderTimeLapseQcifProfile(camcorder_quality quality);
448     static CamcorderProfile *createDefaultCamcorderTimeLapse480pProfile(camcorder_quality quality);
449     static void createDefaultCamcorderTimeLapseLowProfiles(
450             MediaProfiles::CamcorderProfile **lowTimeLapseProfile,
451             MediaProfiles::CamcorderProfile **lowSpecificTimeLapseProfile);
452     static void createDefaultCamcorderTimeLapseHighProfiles(
453             MediaProfiles::CamcorderProfile **highTimeLapseProfile,
454             MediaProfiles::CamcorderProfile **highSpecificTimeLapseProfile);
455 
456     static void createDefaultCamcorderProfiles(MediaProfiles *profiles);
457     static void createDefaultVideoEncoders(MediaProfiles *profiles);
458     static void createDefaultAudioEncoders(MediaProfiles *profiles);
459     static void createDefaultVideoDecoders(MediaProfiles *profiles);
460     static void createDefaultAudioDecoders(MediaProfiles *profiles);
461     static void createDefaultEncoderOutputFileFormats(MediaProfiles *profiles);
462     static void createDefaultImageEncodingQualityLevels(MediaProfiles *profiles);
463     static void createDefaultImageDecodingMaxMemory(MediaProfiles *profiles);
464     static void createDefaultVideoEditorCap(MediaProfiles *profiles);
465     static void createDefaultExportVideoProfiles(MediaProfiles *profiles);
466 
467     static VideoEncoderCap* createDefaultH263VideoEncoderCap();
468     static VideoEncoderCap* createDefaultM4vVideoEncoderCap();
469     static AudioEncoderCap* createDefaultAmrNBEncoderCap();
470 
471     static int findTagForName(const NameToTagMap *map, size_t nMappings, const char *name);
472 
473     /**
474      * Check on existing profiles with the following criteria:
475      * 1. Low quality profile must have the lowest video
476      *    resolution product (width x height)
477      * 2. High quality profile must have the highest video
478      *    resolution product (width x height)
479      *
480      * and add required low/high quality camcorder/timelapse
481      * profiles if they are not found. This allows to remove
482      * duplicate profile definitions in the media_profiles.xml
483      * file.
484      */
485     void checkAndAddRequiredProfilesIfNecessary();
486 
487 
488     // Mappings from name (for instance, codec name) to enum value
489     static const NameToTagMap sVideoEncoderNameMap[];
490     static const NameToTagMap sAudioEncoderNameMap[];
491     static const NameToTagMap sFileFormatMap[];
492     static const NameToTagMap sVideoDecoderNameMap[];
493     static const NameToTagMap sAudioDecoderNameMap[];
494     static const NameToTagMap sCamcorderQualityNameMap[];
495 
496     static bool sIsInitialized;
497     static MediaProfiles *sInstance;
498     static Mutex sLock;
499     int mCurrentCameraId;
500 
501     Vector<CamcorderProfile*> mCamcorderProfiles;
502     Vector<AudioEncoderCap*>  mAudioEncoders;
503     Vector<VideoEncoderCap*>  mVideoEncoders;
504     Vector<AudioDecoderCap*>  mAudioDecoders;
505     Vector<VideoDecoderCap*>  mVideoDecoders;
506     Vector<output_format>     mEncoderOutputFileFormats;
507     Vector<ImageEncodingQualityLevels *>  mImageEncodingQualityLevels;
508     KeyedVector<int, int> mStartTimeOffsets;
509 
510     typedef struct {
511         bool mHasRefProfile;      // Refers to an existing profile
512         int  mRefProfileIndex;    // Reference profile index
513         int  mResolutionProduct;  // width x height
514     } RequiredProfileRefInfo;     // Required low and high profiles
515 
516     typedef struct {
517         RequiredProfileRefInfo mRefs[kNumRequiredProfiles];
518         int mCameraId;
519     } RequiredProfiles;
520 
521     RequiredProfiles *mRequiredProfileRefs;
522     Vector<int>              mCameraIds;
523     VideoEditorCap* mVideoEditorCap;
524     Vector<ExportVideoProfile*> mVideoEditorExportProfiles;
525 };
526 
527 }; // namespace android
528 
529 #endif // ANDROID_MEDIAPROFILES_H
530