| /* |
| ** |
| ** Copyright 2010, The Android Open Source Project. |
| ** |
| ** Licensed under the Apache License, Version 2.0 (the "License"); |
| ** you may not use this file except in compliance with the License. |
| ** You may obtain a copy of the License at |
| ** |
| ** http://www.apache.org/licenses/LICENSE-2.0 |
| ** |
| ** Unless required by applicable law or agreed to in writing, software |
| ** distributed under the License is distributed on an "AS IS" BASIS, |
| ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| ** See the License for the specific language governing permissions and |
| ** limitations under the License. |
| */ |
| |
| #ifndef ANDROID_MEDIAPROFILES_H |
| #define ANDROID_MEDIAPROFILES_H |
| |
| #include <utils/threads.h> |
| #include <media/mediarecorder.h> |
| |
| namespace android { |
| |
| enum camcorder_quality { |
| CAMCORDER_QUALITY_LIST_START = 0, |
| CAMCORDER_QUALITY_LOW = 0, |
| CAMCORDER_QUALITY_HIGH = 1, |
| CAMCORDER_QUALITY_QCIF = 2, |
| CAMCORDER_QUALITY_CIF = 3, |
| CAMCORDER_QUALITY_480P = 4, |
| CAMCORDER_QUALITY_720P = 5, |
| CAMCORDER_QUALITY_1080P = 6, |
| CAMCORDER_QUALITY_QVGA = 7, |
| CAMCORDER_QUALITY_LIST_END = 7, |
| |
| CAMCORDER_QUALITY_TIME_LAPSE_LIST_START = 1000, |
| CAMCORDER_QUALITY_TIME_LAPSE_LOW = 1000, |
| CAMCORDER_QUALITY_TIME_LAPSE_HIGH = 1001, |
| CAMCORDER_QUALITY_TIME_LAPSE_QCIF = 1002, |
| CAMCORDER_QUALITY_TIME_LAPSE_CIF = 1003, |
| CAMCORDER_QUALITY_TIME_LAPSE_480P = 1004, |
| CAMCORDER_QUALITY_TIME_LAPSE_720P = 1005, |
| CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006, |
| CAMCORDER_QUALITY_TIME_LAPSE_QVGA = 1007, |
| CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1007, |
| }; |
| |
| /** |
| * Set CIF as default maximum import and export resolution of video editor. |
| * The maximum import and export resolutions are platform specific, |
| * which should be defined in media_profiles.xml. |
| * Set default maximum prefetch YUV frames to 6, which means video editor can |
| * queue up to 6 YUV frames in the video encoder source. |
| * This value is used to limit the amount of memory used by video editor |
| * engine when the encoder consumes YUV frames at a lower speed |
| * than video editor engine produces. |
| */ |
| enum videoeditor_capability { |
| VIDEOEDITOR_DEFAULT_MAX_INPUT_FRAME_WIDTH = 352, |
| VIDEOEDITOR_DEFUALT_MAX_INPUT_FRAME_HEIGHT = 288, |
| VIDEOEDITOR_DEFAULT_MAX_OUTPUT_FRAME_WIDTH = 352, |
| VIDEOEDITOR_DEFUALT_MAX_OUTPUT_FRAME_HEIGHT = 288, |
| VIDEOEDITOR_DEFAULT_MAX_PREFETCH_YUV_FRAMES = 6 |
| }; |
| |
| enum video_decoder { |
| VIDEO_DECODER_WMV, |
| }; |
| |
| enum audio_decoder { |
| AUDIO_DECODER_WMA, |
| }; |
| |
| |
| class MediaProfiles |
| { |
| public: |
| |
| /** |
| * Returns the singleton instance for subsequence queries. |
| * or NULL if error. |
| */ |
| static MediaProfiles* getInstance(); |
| |
| /** |
| * Returns the value for the given param name for the given camera at |
| * the given quality level, or -1 if error. |
| * |
| * Supported param name are: |
| * duration - the recording duration. |
| * file.format - output file format. see mediarecorder.h for details |
| * vid.codec - video encoder. see mediarecorder.h for details. |
| * aud.codec - audio encoder. see mediarecorder.h for details. |
| * vid.width - video frame width |
| * vid.height - video frame height |
| * vid.fps - video frame rate |
| * vid.bps - video bit rate |
| * aud.bps - audio bit rate |
| * aud.hz - audio sample rate |
| * aud.ch - number of audio channels |
| */ |
| int getCamcorderProfileParamByName(const char *name, int cameraId, |
| camcorder_quality quality) const; |
| |
| /** |
| * Returns true if a profile for the given camera at the given quality exists, |
| * or false if not. |
| */ |
| bool hasCamcorderProfile(int cameraId, camcorder_quality quality) const; |
| |
| /** |
| * Returns the output file formats supported. |
| */ |
| Vector<output_format> getOutputFileFormats() const; |
| |
| /** |
| * Returns the video encoders supported. |
| */ |
| Vector<video_encoder> getVideoEncoders() const; |
| |
| /** |
| * Returns the value for the given param name for the given video encoder |
| * returned from getVideoEncoderByIndex or -1 if error. |
| * |
| * Supported param name are: |
| * enc.vid.width.min - min video frame width |
| * enc.vid.width.max - max video frame width |
| * enc.vid.height.min - min video frame height |
| * enc.vid.height.max - max video frame height |
| * enc.vid.bps.min - min bit rate in bits per second |
| * enc.vid.bps.max - max bit rate in bits per second |
| * enc.vid.fps.min - min frame rate in frames per second |
| * enc.vid.fps.max - max frame rate in frames per second |
| */ |
| int getVideoEncoderParamByName(const char *name, video_encoder codec) const; |
| |
| /** |
| * Returns the value for the given param name for the video editor cap |
| * param or -1 if error. |
| * Supported param name are: |
| * videoeditor.input.width.max - max input video frame width |
| * videoeditor.input.height.max - max input video frame height |
| * videoeditor.output.width.max - max output video frame width |
| * videoeditor.output.height.max - max output video frame height |
| * maxPrefetchYUVFrames - max prefetch YUV frames in video editor engine. This value is used |
| * to limit the memory consumption. |
| */ |
| int getVideoEditorCapParamByName(const char *name) const; |
| |
| /** |
| * Returns the value for the given param name for the video editor export codec format |
| * param or -1 if error. |
| * Supported param name are: |
| * videoeditor.export.profile - export video profile |
| * videoeditor.export.level - export video level |
| * Supported param codec are: |
| * 1 for h263 |
| * 2 for h264 |
| * 3 for mpeg4 |
| */ |
| int getVideoEditorExportParamByName(const char *name, int codec) const; |
| |
| /** |
| * Returns the audio encoders supported. |
| */ |
| Vector<audio_encoder> getAudioEncoders() const; |
| |
| /** |
| * Returns the value for the given param name for the given audio encoder |
| * returned from getAudioEncoderByIndex or -1 if error. |
| * |
| * Supported param name are: |
| * enc.aud.ch.min - min number of channels |
| * enc.aud.ch.max - max number of channels |
| * enc.aud.bps.min - min bit rate in bits per second |
| * enc.aud.bps.max - max bit rate in bits per second |
| * enc.aud.hz.min - min sample rate in samples per second |
| * enc.aud.hz.max - max sample rate in samples per second |
| */ |
| int getAudioEncoderParamByName(const char *name, audio_encoder codec) const; |
| |
| /** |
| * Returns the video decoders supported. |
| */ |
| Vector<video_decoder> getVideoDecoders() const; |
| |
| /** |
| * Returns the audio decoders supported. |
| */ |
| Vector<audio_decoder> getAudioDecoders() const; |
| |
| /** |
| * Returns the number of image encoding quality levels supported. |
| */ |
| Vector<int> getImageEncodingQualityLevels(int cameraId) const; |
| |
| /** |
| * Returns the start time offset (in ms) for the given camera Id. |
| * If the given camera Id does not exist, -1 will be returned. |
| */ |
| int getStartTimeOffsetMs(int cameraId) const; |
| |
| private: |
| enum { |
| // Camcorder profiles (high/low) and timelapse profiles (high/low) |
| kNumRequiredProfiles = 4, |
| }; |
| |
| MediaProfiles& operator=(const MediaProfiles&); // Don't call me |
| MediaProfiles(const MediaProfiles&); // Don't call me |
| MediaProfiles() { mVideoEditorCap = NULL; } // Dummy default constructor |
| ~MediaProfiles(); // Don't delete me |
| |
| struct VideoCodec { |
| VideoCodec(video_encoder codec, int bitRate, int frameWidth, int frameHeight, int frameRate) |
| : mCodec(codec), |
| mBitRate(bitRate), |
| mFrameWidth(frameWidth), |
| mFrameHeight(frameHeight), |
| mFrameRate(frameRate) {} |
| |
| VideoCodec(const VideoCodec& copy) { |
| mCodec = copy.mCodec; |
| mBitRate = copy.mBitRate; |
| mFrameWidth = copy.mFrameWidth; |
| mFrameHeight = copy.mFrameHeight; |
| mFrameRate = copy.mFrameRate; |
| } |
| |
| ~VideoCodec() {} |
| |
| video_encoder mCodec; |
| int mBitRate; |
| int mFrameWidth; |
| int mFrameHeight; |
| int mFrameRate; |
| }; |
| |
| struct AudioCodec { |
| AudioCodec(audio_encoder codec, int bitRate, int sampleRate, int channels) |
| : mCodec(codec), |
| mBitRate(bitRate), |
| mSampleRate(sampleRate), |
| mChannels(channels) {} |
| |
| AudioCodec(const AudioCodec& copy) { |
| mCodec = copy.mCodec; |
| mBitRate = copy.mBitRate; |
| mSampleRate = copy.mSampleRate; |
| mChannels = copy.mChannels; |
| } |
| |
| ~AudioCodec() {} |
| |
| audio_encoder mCodec; |
| int mBitRate; |
| int mSampleRate; |
| int mChannels; |
| }; |
| |
| struct CamcorderProfile { |
| CamcorderProfile() |
| : mCameraId(0), |
| mFileFormat(OUTPUT_FORMAT_THREE_GPP), |
| mQuality(CAMCORDER_QUALITY_HIGH), |
| mDuration(0), |
| mVideoCodec(0), |
| mAudioCodec(0) {} |
| |
| CamcorderProfile(const CamcorderProfile& copy) { |
| mCameraId = copy.mCameraId; |
| mFileFormat = copy.mFileFormat; |
| mQuality = copy.mQuality; |
| mDuration = copy.mDuration; |
| mVideoCodec = new VideoCodec(*copy.mVideoCodec); |
| mAudioCodec = new AudioCodec(*copy.mAudioCodec); |
| } |
| |
| ~CamcorderProfile() { |
| delete mVideoCodec; |
| delete mAudioCodec; |
| } |
| |
| int mCameraId; |
| output_format mFileFormat; |
| camcorder_quality mQuality; |
| int mDuration; |
| VideoCodec *mVideoCodec; |
| AudioCodec *mAudioCodec; |
| }; |
| |
| struct VideoEncoderCap { |
| // Ugly constructor |
| VideoEncoderCap(video_encoder codec, |
| int minBitRate, int maxBitRate, |
| int minFrameWidth, int maxFrameWidth, |
| int minFrameHeight, int maxFrameHeight, |
| int minFrameRate, int maxFrameRate) |
| : mCodec(codec), |
| mMinBitRate(minBitRate), mMaxBitRate(maxBitRate), |
| mMinFrameWidth(minFrameWidth), mMaxFrameWidth(maxFrameWidth), |
| mMinFrameHeight(minFrameHeight), mMaxFrameHeight(maxFrameHeight), |
| mMinFrameRate(minFrameRate), mMaxFrameRate(maxFrameRate) {} |
| |
| ~VideoEncoderCap() {} |
| |
| video_encoder mCodec; |
| int mMinBitRate, mMaxBitRate; |
| int mMinFrameWidth, mMaxFrameWidth; |
| int mMinFrameHeight, mMaxFrameHeight; |
| int mMinFrameRate, mMaxFrameRate; |
| }; |
| |
| struct AudioEncoderCap { |
| // Ugly constructor |
| AudioEncoderCap(audio_encoder codec, |
| int minBitRate, int maxBitRate, |
| int minSampleRate, int maxSampleRate, |
| int minChannels, int maxChannels) |
| : mCodec(codec), |
| mMinBitRate(minBitRate), mMaxBitRate(maxBitRate), |
| mMinSampleRate(minSampleRate), mMaxSampleRate(maxSampleRate), |
| mMinChannels(minChannels), mMaxChannels(maxChannels) {} |
| |
| ~AudioEncoderCap() {} |
| |
| audio_encoder mCodec; |
| int mMinBitRate, mMaxBitRate; |
| int mMinSampleRate, mMaxSampleRate; |
| int mMinChannels, mMaxChannels; |
| }; |
| |
| struct VideoDecoderCap { |
| VideoDecoderCap(video_decoder codec): mCodec(codec) {} |
| ~VideoDecoderCap() {} |
| |
| video_decoder mCodec; |
| }; |
| |
| struct AudioDecoderCap { |
| AudioDecoderCap(audio_decoder codec): mCodec(codec) {} |
| ~AudioDecoderCap() {} |
| |
| audio_decoder mCodec; |
| }; |
| |
| struct NameToTagMap { |
| const char* name; |
| int tag; |
| }; |
| |
| struct ImageEncodingQualityLevels { |
| int mCameraId; |
| Vector<int> mLevels; |
| }; |
| struct ExportVideoProfile { |
| ExportVideoProfile(int codec, int profile, int level) |
| :mCodec(codec),mProfile(profile),mLevel(level) {} |
| ~ExportVideoProfile() {} |
| int mCodec; |
| int mProfile; |
| int mLevel; |
| }; |
| struct VideoEditorCap { |
| VideoEditorCap(int inFrameWidth, int inFrameHeight, |
| int outFrameWidth, int outFrameHeight, int frames) |
| : mMaxInputFrameWidth(inFrameWidth), |
| mMaxInputFrameHeight(inFrameHeight), |
| mMaxOutputFrameWidth(outFrameWidth), |
| mMaxOutputFrameHeight(outFrameHeight), |
| mMaxPrefetchYUVFrames(frames) {} |
| |
| ~VideoEditorCap() {} |
| |
| int mMaxInputFrameWidth; |
| int mMaxInputFrameHeight; |
| int mMaxOutputFrameWidth; |
| int mMaxOutputFrameHeight; |
| int mMaxPrefetchYUVFrames; |
| }; |
| |
| int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const; |
| void initRequiredProfileRefs(const Vector<int>& cameraIds); |
| int getRequiredProfileRefIndex(int cameraId); |
| |
| // Debug |
| static void logVideoCodec(const VideoCodec& codec); |
| static void logAudioCodec(const AudioCodec& codec); |
| static void logVideoEncoderCap(const VideoEncoderCap& cap); |
| static void logAudioEncoderCap(const AudioEncoderCap& cap); |
| static void logVideoDecoderCap(const VideoDecoderCap& cap); |
| static void logAudioDecoderCap(const AudioDecoderCap& cap); |
| static void logVideoEditorCap(const VideoEditorCap& cap); |
| |
| // If the xml configuration file does exist, use the settings |
| // from the xml |
| static MediaProfiles* createInstanceFromXmlFile(const char *xml); |
| static output_format createEncoderOutputFileFormat(const char **atts); |
| static VideoCodec* createVideoCodec(const char **atts, MediaProfiles *profiles); |
| static AudioCodec* createAudioCodec(const char **atts, MediaProfiles *profiles); |
| static AudioDecoderCap* createAudioDecoderCap(const char **atts); |
| static VideoDecoderCap* createVideoDecoderCap(const char **atts); |
| static VideoEncoderCap* createVideoEncoderCap(const char **atts); |
| static AudioEncoderCap* createAudioEncoderCap(const char **atts); |
| static VideoEditorCap* createVideoEditorCap( |
| const char **atts, MediaProfiles *profiles); |
| static ExportVideoProfile* createExportVideoProfile(const char **atts); |
| |
| static CamcorderProfile* createCamcorderProfile( |
| int cameraId, const char **atts, Vector<int>& cameraIds); |
| |
| static int getCameraId(const char **atts); |
| |
| void addStartTimeOffset(int cameraId, const char **atts); |
| |
| ImageEncodingQualityLevels* findImageEncodingQualityLevels(int cameraId) const; |
| void addImageEncodingQualityLevel(int cameraId, const char** atts); |
| |
| // Customized element tag handler for parsing the xml configuration file. |
| static void startElementHandler(void *userData, const char *name, const char **atts); |
| |
| // If the xml configuration file does not exist, use hard-coded values |
| static MediaProfiles* createDefaultInstance(); |
| |
| static CamcorderProfile *createDefaultCamcorderQcifProfile(camcorder_quality quality); |
| static CamcorderProfile *createDefaultCamcorderCifProfile(camcorder_quality quality); |
| static void createDefaultCamcorderLowProfiles( |
| MediaProfiles::CamcorderProfile **lowProfile, |
| MediaProfiles::CamcorderProfile **lowSpecificProfile); |
| static void createDefaultCamcorderHighProfiles( |
| MediaProfiles::CamcorderProfile **highProfile, |
| MediaProfiles::CamcorderProfile **highSpecificProfile); |
| |
| static CamcorderProfile *createDefaultCamcorderTimeLapseQcifProfile(camcorder_quality quality); |
| static CamcorderProfile *createDefaultCamcorderTimeLapse480pProfile(camcorder_quality quality); |
| static void createDefaultCamcorderTimeLapseLowProfiles( |
| MediaProfiles::CamcorderProfile **lowTimeLapseProfile, |
| MediaProfiles::CamcorderProfile **lowSpecificTimeLapseProfile); |
| static void createDefaultCamcorderTimeLapseHighProfiles( |
| MediaProfiles::CamcorderProfile **highTimeLapseProfile, |
| MediaProfiles::CamcorderProfile **highSpecificTimeLapseProfile); |
| |
| static void createDefaultCamcorderProfiles(MediaProfiles *profiles); |
| static void createDefaultVideoEncoders(MediaProfiles *profiles); |
| static void createDefaultAudioEncoders(MediaProfiles *profiles); |
| static void createDefaultVideoDecoders(MediaProfiles *profiles); |
| static void createDefaultAudioDecoders(MediaProfiles *profiles); |
| static void createDefaultEncoderOutputFileFormats(MediaProfiles *profiles); |
| static void createDefaultImageEncodingQualityLevels(MediaProfiles *profiles); |
| static void createDefaultImageDecodingMaxMemory(MediaProfiles *profiles); |
| static void createDefaultVideoEditorCap(MediaProfiles *profiles); |
| static void createDefaultExportVideoProfiles(MediaProfiles *profiles); |
| |
| static VideoEncoderCap* createDefaultH263VideoEncoderCap(); |
| static VideoEncoderCap* createDefaultM4vVideoEncoderCap(); |
| static AudioEncoderCap* createDefaultAmrNBEncoderCap(); |
| |
| static int findTagForName(const NameToTagMap *map, size_t nMappings, const char *name); |
| |
| /** |
| * Check on existing profiles with the following criteria: |
| * 1. Low quality profile must have the lowest video |
| * resolution product (width x height) |
| * 2. High quality profile must have the highest video |
| * resolution product (width x height) |
| * |
| * and add required low/high quality camcorder/timelapse |
| * profiles if they are not found. This allows to remove |
| * duplicate profile definitions in the media_profiles.xml |
| * file. |
| */ |
| void checkAndAddRequiredProfilesIfNecessary(); |
| |
| |
| // Mappings from name (for instance, codec name) to enum value |
| static const NameToTagMap sVideoEncoderNameMap[]; |
| static const NameToTagMap sAudioEncoderNameMap[]; |
| static const NameToTagMap sFileFormatMap[]; |
| static const NameToTagMap sVideoDecoderNameMap[]; |
| static const NameToTagMap sAudioDecoderNameMap[]; |
| static const NameToTagMap sCamcorderQualityNameMap[]; |
| |
| static bool sIsInitialized; |
| static MediaProfiles *sInstance; |
| static Mutex sLock; |
| int mCurrentCameraId; |
| |
| Vector<CamcorderProfile*> mCamcorderProfiles; |
| Vector<AudioEncoderCap*> mAudioEncoders; |
| Vector<VideoEncoderCap*> mVideoEncoders; |
| Vector<AudioDecoderCap*> mAudioDecoders; |
| Vector<VideoDecoderCap*> mVideoDecoders; |
| Vector<output_format> mEncoderOutputFileFormats; |
| Vector<ImageEncodingQualityLevels *> mImageEncodingQualityLevels; |
| KeyedVector<int, int> mStartTimeOffsets; |
| |
| typedef struct { |
| bool mHasRefProfile; // Refers to an existing profile |
| int mRefProfileIndex; // Reference profile index |
| int mResolutionProduct; // width x height |
| } RequiredProfileRefInfo; // Required low and high profiles |
| |
| typedef struct { |
| RequiredProfileRefInfo mRefs[kNumRequiredProfiles]; |
| int mCameraId; |
| } RequiredProfiles; |
| |
| RequiredProfiles *mRequiredProfileRefs; |
| Vector<int> mCameraIds; |
| VideoEditorCap* mVideoEditorCap; |
| Vector<ExportVideoProfile*> mVideoEditorExportProfiles; |
| }; |
| |
| }; // namespace android |
| |
| #endif // ANDROID_MEDIAPROFILES_H |