Home | History | Annotate | Download | only in media
      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
    224     MediaProfiles() { mVideoEditorCap = NULL; }        // Dummy default constructor
    225     ~MediaProfiles();                                // Don't delete me
    226 
    227     struct VideoCodec {
    228         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 
    235         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 
    243         ~VideoCodec() {}
    244 
    245         video_encoder mCodec;
    246         int mBitRate;
    247         int mFrameWidth;
    248         int mFrameHeight;
    249         int mFrameRate;
    250     };
    251 
    252     struct AudioCodec {
    253         AudioCodec(audio_encoder codec, int bitRate, int sampleRate, int channels)
    254             : mCodec(codec),
    255               mBitRate(bitRate),
    256               mSampleRate(sampleRate),
    257               mChannels(channels) {}
    258 
    259         AudioCodec(const AudioCodec& copy) {
    260             mCodec = copy.mCodec;
    261             mBitRate = copy.mBitRate;
    262             mSampleRate = copy.mSampleRate;
    263             mChannels = copy.mChannels;
    264         }
    265 
    266         ~AudioCodec() {}
    267 
    268         audio_encoder mCodec;
    269         int mBitRate;
    270         int mSampleRate;
    271         int mChannels;
    272     };
    273 
    274     struct CamcorderProfile {
    275         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 
    283         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 
    292         ~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
    307         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 
    318          ~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
    329         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 
    338         ~AudioEncoderCap() {}
    339 
    340         audio_encoder mCodec;
    341         int mMinBitRate, mMaxBitRate;
    342         int mMinSampleRate, mMaxSampleRate;
    343         int mMinChannels, mMaxChannels;
    344     };
    345 
    346     struct VideoDecoderCap {
    347         VideoDecoderCap(video_decoder codec): mCodec(codec) {}
    348         ~VideoDecoderCap() {}
    349 
    350         video_decoder mCodec;
    351     };
    352 
    353     struct AudioDecoderCap {
    354         AudioDecoderCap(audio_decoder codec): mCodec(codec) {}
    355         ~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 {
    370         ExportVideoProfile(int codec, int profile, int level)
    371             :mCodec(codec),mProfile(profile),mLevel(level) {}
    372         ~ExportVideoProfile() {}
    373         int mCodec;
    374         int mProfile;
    375         int mLevel;
    376     };
    377     struct VideoEditorCap {
    378         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 
    386         ~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