/* ------------------------------------------------------------------ * Copyright (C) 1998-2009 PacketVideo * * 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. * ------------------------------------------------------------------- */ /*********************************************************************************/ /* File: cvei.h */ /* Purpose: */ /* Date: */ /* Revision History: */ /** @introduction Common Video Encoder Interface (CVEI) is intended to be used by application developers who want to create a multimedia application with video encoding feature. CVEI is designed such that new video encoder algorithms or modules can be plugged in seamlessly without user interaction. In other words, any changes to the CVEI library are transparent to the users. Users can still use the same set of APIs for new encoding tools. @requirement CVEI will take an input frame in one of several format supported by PV and encode it to an MPEG4 bitstream. It will also return a reconstructed image in YUV 4:2:0 format. Currently the input format supported are YUV 4:2:0, RGB24 and UYVY 4:2:2. CVEI is designed such that it is simple to use. It should hides implementation dependency from the users. In this version, we decided that the operation will be synchronous, i.e., the encoding will be a blocked call. Asynchronous operation will be in the level above CVEI, i.e., in Author Engine Video Module which will take care of capturing device as well. @brief The following classes are used to interface with codecs. Their names are CPVxxxVideoEncoder where xxx is codec specific such as MPEG4, H263, H26L, etc. All of them are subclasses of CPVCommonVideoEncoder. */ /*********************************************************************************/ #ifndef __CVEI_H #define __CVEI_H #include "oscl_scheduler_ao.h" #include "oscl_base.h" #include "mp4enc_api.h" /* for MP4HintTrack */ #define MAX_LAYER 2 /** General returned values. */ enum TCVEI_RETVAL { ECVEI_SUCCESS, ECVEI_FAIL, ECVEI_FLUSH, ECVEI_MORE_OUTPUT } ; /** Returned events with the callback function. */ enum TCVEI_EVENT { /** Called when a packet or a frame of output bitstream is ready. */ ECVEI_BUFFER_READY, /** Called when the last packet of a frame of output bitstream is ready. */ ECVEI_FRAME_DONE, /** Called when no buffers is available for output bitstream. A buffer can be added thru AddBuffer API. */ ECVEI_NO_BUFFERS, /** Called when there is an error with the encoding operation. */ ECVEI_ERROR }; /** Contains supported input format */ enum TPVVideoFormat { ECVEI_RGB24, ECVEI_RGB12, ECVEI_YUV420, ECVEI_UYVY, ECVEI_YUV420SEMIPLANAR }; /** Type of contents for optimal encoding mode. */ enum TPVContentType { /** Content is to be streamed in real-time. */ ECVEI_STREAMING, /** Content is to be downloaded and playbacked later.*/ ECVEI_DOWNLOAD, /** Content is to be 3gpp baseline compliant. */ ECVEI_H263 }; /** Rate control type. */ enum TMP4RateControlType { /** Constant quality, variable bit rate, fixed quantization level. */ ECONSTANT_Q, /** Short-term constant bit rate control. */ ECBR_1, /** Long-term constant bit rate control. */ EVBR_1 }; /** Targeted profile and level to encode. */ enum TPVM4VProfileLevel { /* Non-scalable profile */ ECVEI_SIMPLE_LEVEL0 = 0, ECVEI_SIMPLE_LEVEL1, ECVEI_SIMPLE_LEVEL2, ECVEI_SIMPLE_LEVEL3, ECVEI_CORE_LEVEL1, ECVEI_CORE_LEVEL2, /* Scalable profile */ ECVEI_SIMPLE_SCALABLE_LEVEL0 = 6, ECVEI_SIMPLE_SCALABLE_LEVEL1, ECVEI_SIMPLE_SCALABLE_LEVEL2, ECVEI_CORE_SCALABLE_LEVEL1 = 10, ECVEI_CORE_SCALABLE_LEVEL2, ECVEI_CORE_SCALABLE_LEVEL3 }; /** This structure contains encoder settings. */ struct TPVVideoEncodeParam { /** Specifies an ID that will be used to specify this encoder while returning the bitstream in asynchronous mode. */ uint32 iEncodeID; /** Specifies whether base only (iNumLayer = 1) or base + enhancement layer (iNumLayer =2 ) is to be used. */ int32 iNumLayer; /** Specifies the width in pixels of the encoded frames. IFrameWidth[0] is for base layer and iFrameWidth[1] is for enhanced layer. */ int iFrameWidth[MAX_LAYER]; /** Specifies the height in pixels of the encoded frames. IFrameHeight[0] is for base layer and iFrameHeight[1] is for enhanced layer. */ int iFrameHeight[MAX_LAYER]; /** Specifies the cumulative bit rate in bit per second. IBitRate[0] is for base layer and iBitRate[1] is for base+enhanced layer.*/ int iBitRate[MAX_LAYER]; /** Specifies the cumulative frame rate in frame per second. IFrameRate[0] is for base layer and iFrameRate[1] is for base+enhanced layer. */ float iFrameRate[MAX_LAYER]; /** Specifies the picture quality factor on the scale of 1 to 10. It trades off the picture quality with the frame rate. Higher frame quality means lower frame rate. Lower frame quality for higher frame rate.*/ int32 iFrameQuality; /** Enable the use of iFrameQuality to determine the frame rate. If it is false, the encoder will try to meet the specified frame rate regardless of the frame quality.*/ bool iEnableFrameQuality; /** Specifies the maximum number of P-frames between 2 INTRA frames. An INTRA mode is forced to a frame once this interval is reached. When there is only one I-frame is present at the beginning of the clip, iIFrameInterval should be set to -1. */ int32 iIFrameInterval; /** According to iIFrameInterval setting, the minimum number of intra MB per frame is optimally calculated for error resiliency. However, when iIFrameInterval is set to -1, iNumIntraMBRefresh must be specified to guarantee the minimum number of intra macroblocks per frame.*/ uint32 iNumIntraMBRefresh; /** Specifies the VBV buffer size which determines the end-to-end delay between the encoder and the decoder. The size is in unit of seconds. For download application, the buffer size can be larger than the streaming application. For 2-way application, this buffer shall be kept minimal. For a special case, in VBR mode, iBufferDelay will be set to -1 to allow buffer underflow. */ float iBufferDelay; /** Specifies the type of the access whether it is streaming, CVEI_STREAMING (data partitioning mode) or download, CVEI_DOWNLOAD (combined mode).*/ TPVContentType iContentType; /** Specifies the rate control algorithm among one of the following constant Q, CBR and VBR. The structure TMP4RateControlType is defined below.*/ TMP4RateControlType iRateControlType; /** Specifies high quality but also high complexity mode for rate control. */ bool iRDOptimal; /** Specifies the initial quantization parameter for the first I-frame. If constant Q rate control is used, this QP will be used for all the I-frames. This number must be set between 1 and 31, otherwise, Initialize() will fail. */ int iIquant[2]; /** Specifies the initial quantization parameter for the first P-frame. If constant Q rate control is used, this QP will be used for all the P-frames. This number must be set between 1 and 31, otherwise, Initialize() will fail. */ int iPquant[2]; /** Specifies the initial quantization parameter for the first B-frame. If constant Q rate control is used, this QP will be used for all the B-frames. This number must be set between 1 and 31, otherwise, Initialize() will fail. */ int iBquant[2]; /** Specifies the search range in pixel unit for motion vector. The range of the motion vector will be of dimension [-iSearchRange.5, +iSearchRange.0]. */ int32 iSearchRange; /** Specifies the use of 8x8 motion vectors. */ bool iMV8x8; /** Specifies the use of half-pel motion vectors. */ bool iMVHalfPel; /** Specifies automatic scene detection where I-frame will be used the the first frame in a new scene. */ bool iSceneDetection; /** Specifies the packet size in bytes which represents the number of bytes between two resync markers. For ECVEI_DOWNLOAD and ECVEI_H263, if iPacketSize is set to 0, there will be no resync markers in the bitstream. For ECVEI_STREAMING is parameter must be set to a value greater than 0.*/ uint32 iPacketSize; /** Specifies whether the current frame skipping decision is allowed after encoding the current frame. If there is no memory of what has been coded for the current frame, iNoCurrentSkip has to be on. */ bool iNoCurrentSkip; /** Specifies that no frame skipping is allowed. Frame skipping is a tool used to control the average number of bits spent to meet the target bit rate. */ bool iNoFrameSkip; /** Specifies the duration of the clip in millisecond.*/ int32 iClipDuration; /** Specifies the profile and level used to encode the bitstream. When present, other settings will be checked against the range allowable by this target profile and level. Fail may be returned from the Initialize call. */ TPVM4VProfileLevel iProfileLevel; /** Specifies FSI Buffer input */ uint8* iFSIBuff; /** Specifies FSI Buffer Length */ int iFSIBuffLength; }; /** Structure for input format information */ struct TPVVideoInputFormat { /** Contains the width in pixels of the input frame. */ int32 iFrameWidth; /** Contains the height in pixels of the input frame. */ int32 iFrameHeight; /** Contains the input frame rate in the unit of frame per second. */ float iFrameRate; /** Contains Frame Orientation. Used for RGB input. 1 means Bottom_UP RGB, 0 means Top_Down RGB, -1 for video formats other than RGB*/ int iFrameOrientation; /** Contains the format of the input video, e.g., YUV 4:2:0, UYVY, RGB24, etc. */ TPVVideoFormat iVideoFormat; }; /** Contains the input data information */ struct TPVVideoInputData { /** Pointer to an input frame buffer in input source format.*/ uint8 *iSource; /** The corresponding time stamp of the input frame. */ uint32 iTimeStamp; }; /** Contains the output data information */ struct TPVVideoOutputData { /** Pointer to the reconstructed frame buffer in YUV 4:2:0 domain. */ uint8 *iFrame; /** The number of layer encoded, 0 for base, 1 for enhanced. */ int32 iLayerNumber; /** Pointer to the encoded bitstream buffer. */ uint8 *iBitStream; /** The size in bytes of iBStream. */ int32 iBitStreamSize; /** The time stamp of the encoded frame according to the bitstream. */ uint32 iVideoTimeStamp; /** The time stamp of the encoded frame as given before the encoding. */ uint32 iExternalTimeStamp; /** The hint track information. */ MP4HintTrack iHintTrack; }; /** An observer class for callbacks to report the status of the CVEI */ class MPVCVEIObserver { public: /** The callback funtion with aEvent being one of TCVEIEvent enumeration. */ virtual void HandlePVCVEIEvent (uint32 aId, uint32 aEvent, uint32 aParam1 = 0) = 0; virtual ~MPVCVEIObserver() {} }; /** This class is the base class for codec specific interface class. The users must maintain an instance of the codec specific class throughout the encoding session. */ class CommonVideoEncoder : public OsclTimerObject { public: /** Constructor for CVEI class. */ CommonVideoEncoder() : OsclTimerObject(OsclActiveObject::EPriorityNominal, "PVEncoder") {}; /** Initialization function to set the input video format and the encoding parameters. This function returns CVEI_ERROR if there is any errors. Otherwise, the function returns CVEI_SUCCESS.*/ virtual TCVEI_RETVAL Initialize(TPVVideoInputFormat *aVidInFormat, TPVVideoEncodeParam *aEncParam) = 0; /** Set the observer for asynchronous encoding mode. */ virtual TCVEI_RETVAL SetObserver(MPVCVEIObserver *aObserver) = 0; /** Add a buffer to the queue of output buffers for output bitstream in asynchronous encoding mode. */ virtual TCVEI_RETVAL AddBuffer(TPVVideoOutputData *aVidOut) = 0; /** This function sends in an input video data structure containing a source frame and the associated timestamp. The encoded bitstream will be returned by observer callback. The above 3 APIs only replace EncodeFrame() API. Other APIs such as initialization and update parameters remain the same. */ virtual TCVEI_RETVAL Encode(TPVVideoInputData *aVidIn) = 0; /** This function returns the maximum VBV buffer size such that the application can allocate a buffer that guarantees to fit one frame.*/ virtual int32 GetBufferSize() = 0; /** This function returns the VOL header part (starting from the VOS header) of the encoded bitstream. This function must be called after Initialize. The output is written to the memory (volHeader) allocated by the users.*/ virtual TCVEI_RETVAL GetVolHeader(uint8 *volHeader, int32 *size, int32 layer) = 0; /** This function sends in an input video data structure containing a source frame and the associated timestamp. It returns an output video data structure containing coded bit stream, reconstructed frame in YUV 4:2:0 (can be changed to source format) and the timestamp associated with the coded frame. The input timestamp may not correspond to the output timestamp. User can send an input structure in without getting any encoded data back or getting an encoded frame in the past. This function returns ECVEI_ERROR if there is any errors. Otherwise, the function returns ECVEI_SUCCESS. In case of Overrun Buffer usage, it is possible that return value is ECVEI_MORE_OUTPUT which indicates that frame cannot fit in the current buffer*/ virtual TCVEI_RETVAL EncodeFrame(TPVVideoInputData *aVidIn, TPVVideoOutputData *aVidOut, int *aRemainingBytes #ifdef PVAUTHOR_PROFILING , void *aParam1 = 0 #endif ) = 0; /** Before the termination of the encoding process, the users have to query whether there are any encoded frame pending inside the CVEI. The returned value will indicate whether there are more frames to be flushed (ECVEI_FLUSH). FlushOutput has to be called until there are no more frames, i.e., it returns ECVEI_SUCCESS. This function may be called during the encoding operation if there is no input frame and the application does not want to waste the time waiting for input frame. It can call this function to flush encoded frame out of the memory. */ virtual TCVEI_RETVAL FlushOutput(TPVVideoOutputData *aVidOut) = 0; /** This function cleanup the CVEI allocated resources. */ virtual TCVEI_RETVAL Terminate() = 0; /**This function dynamically changes the target bit rate of the encoder while encoding. aBitRate[n] is the new accumulate target bit rate of layer n. Successful update is returned with ECVEI_SUCCESS.*/ virtual TCVEI_RETVAL UpdateBitRate(int32 aNumLayer, int32 *aBitRate) = 0; /** This function dynamically changes the target frame rate of the encoder while encoding. aFrameRate[n] is the new accumulate target frame rate of layer n. Successful update is returned with ECVEI_SUCCESS. */ virtual TCVEI_RETVAL UpdateFrameRate(int32 aNumLayer, float *aFrameRate) = 0; /** This function dynamically changes the I-Vop update interval while encoding to a new value, aIFrameInterval. */ virtual TCVEI_RETVAL UpdateIFrameInterval(int32 aIFrameInterval) = 0; /** This function forces an I-Vop mode to the next frame to be encoded. */ virtual TCVEI_RETVAL IFrameRequest() = 0; /** This function returns the input width of a specific layer (not necessarily multiple of 16). */ virtual int32 GetEncodeWidth(int32 aLayer) = 0; /** This function returns the input height of a specific layer (not necessarily multiple of 16). */ virtual int32 GetEncodeHeight(int32 aLayer) = 0; /** This function returns the target encoded frame rate of a specific layer. */ virtual float GetEncodeFrameRate(int32 aLayer) = 0; protected: virtual void Run(void) = 0; virtual void DoCancel(void) = 0; /* internal enum */ enum TCVEIState { EIdle, EEncode }; TCVEIState iState; uint32 iId; }; #endif