/* * Copyright (c) 2009-2011 Intel Corporation. All rights reserved. * * 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 VIDEO_DECODER_BASE_H_ #define VIDEO_DECODER_BASE_H_ #include <va/va.h> #include <va/va_tpi.h> #include "VideoDecoderDefs.h" #include "VideoDecoderInterface.h" #include <pthread.h> #include <dlfcn.h> extern "C" { #include "vbp_loader.h" } #ifndef Display #ifdef USE_GEN_HW typedef char Display; #else typedef unsigned int Display; #endif #endif // TODO: check what is the best number. Must be at least 2 to support one backward reference frame. // Currently set to 8 to support 7 backward reference frames. This value is used for AVC frame reordering only. // e.g: // POC: 4P, 8P, 10P, 6B and mNextOutputPOC = 5 #define OUTPUT_WINDOW_SIZE 8 /* * ITU-R BT.601, BT.709 transfer matrices from VA 2.0 * Video Color Field definitions Design Spec(Version 0.03). * [R', G', B'] values are in the range [0, 1], Y' is in the range [0,1] * and [Pb, Pr] components are in the range [-0.5, 0.5]. */ static float s601[9] = { 1, -0.000001, 1.402, 1, -0.344136, -0.714136, 1, 1.772, 0 }; static float s709[9] = { 1, 0, 1.5748, 1, -0.187324, -0.468124, 1, 1.8556, 0 }; class VideoDecoderBase : public IVideoDecoder { public: VideoDecoderBase(const char *mimeType, _vbp_parser_type type); virtual ~VideoDecoderBase(); virtual Decode_Status start(VideoConfigBuffer *buffer); virtual Decode_Status reset(VideoConfigBuffer *buffer) ; virtual void stop(void); //virtual Decode_Status decode(VideoDecodeBuffer *buffer); virtual void flush(void); virtual void freeSurfaceBuffers(void); virtual const VideoRenderBuffer* getOutput(bool draining = false, VideoErrorBuffer *output_buf = NULL); virtual Decode_Status signalRenderDone(void * graphichandler, bool isNew = false); virtual const VideoFormatInfo* getFormatInfo(void); virtual bool checkBufferAvail(); virtual void enableErrorReport(bool enabled = false) {mErrReportEnabled = enabled; }; virtual int getOutputQueueLength(void); protected: // each acquireSurfaceBuffer must be followed by a corresponding outputSurfaceBuffer or releaseSurfaceBuffer. // Only one surface buffer can be acquired at any given time virtual Decode_Status acquireSurfaceBuffer(void); // frame is successfully decoded to the acquired surface buffer and surface is ready for output virtual Decode_Status outputSurfaceBuffer(void); // acquired surface buffer is not used virtual Decode_Status releaseSurfaceBuffer(void); // flush all decoded but not rendered buffers virtual void flushSurfaceBuffers(void); virtual Decode_Status endDecodingFrame(bool dropFrame); virtual VideoSurfaceBuffer* findOutputByPoc(bool draining = false); virtual VideoSurfaceBuffer* findOutputByPct(bool draining = false); virtual VideoSurfaceBuffer* findOutputByPts(); virtual Decode_Status setupVA(uint32_t numSurface, VAProfile profile, uint32_t numExtraSurface = 0); virtual Decode_Status terminateVA(void); virtual Decode_Status parseBuffer(uint8_t *buffer, int32_t size, bool config, void** vbpData); static inline uint32_t alignMB(uint32_t a) { return ((a + 15) & (~15)); } virtual Decode_Status getRawDataFromSurface(VideoRenderBuffer *renderBuffer = NULL, uint8_t *pRawData = NULL, uint32_t *pSize = NULL, bool internal = true); #if (defined USE_AVC_SHORT_FORMAT) || (defined USE_SLICE_HEADER_PARSING) Decode_Status updateBuffer(uint8_t *buffer, int32_t size, void** vbpData); Decode_Status queryBuffer(void **vbpData); Decode_Status setParserType(_vbp_parser_type type); virtual Decode_Status getCodecSpecificConfigs(VAProfile profile, VAConfigID *config); #endif virtual Decode_Status checkHardwareCapability(); Decode_Status createSurfaceFromHandle(int32_t index); private: Decode_Status mapSurface(void); void initSurfaceBuffer(bool reset); void drainDecodingErrors(VideoErrorBuffer *outErrBuf, VideoRenderBuffer *currentSurface); void fillDecodingErrors(VideoRenderBuffer *currentSurface); bool mInitialized; pthread_mutex_t mLock; protected: bool mLowDelay; // when true, decoded frame is immediately output for rendering bool mStoreMetaData; // when true, meta data mode is enabled for adaptive playback VideoFormatInfo mVideoFormatInfo; Display *mDisplay; VADisplay mVADisplay; VAContextID mVAContext; VAConfigID mVAConfig; VASurfaceID *mExtraSurfaces; // extra surfaces array int32_t mNumExtraSurfaces; bool mVAStarted; uint64_t mCurrentPTS; // current presentation time stamp (unit is unknown, depend on the framework: GStreamer 100-nanosec, Android: microsecond) // the following three member variables should be set using // acquireSurfaceBuffer/outputSurfaceBuffer/releaseSurfaceBuffer VideoSurfaceBuffer *mAcquiredBuffer; VideoSurfaceBuffer *mLastReference; VideoSurfaceBuffer *mForwardReference; VideoConfigBuffer mConfigBuffer; // only store configure meta data. bool mDecodingFrame; // indicate whether a frame is being decoded bool mSizeChanged; // indicate whether video size is changed. bool mShowFrame; // indicate whether the decoded frame is for display int32_t mOutputWindowSize; // indicate limit of number of outstanding frames for output int32_t mRotationDegrees; pthread_mutex_t mFormatLock; bool mErrReportEnabled; bool mWiDiOn; typedef uint32_t (*OpenFunc)(uint32_t, void **); typedef uint32_t (*CloseFunc)(void *); typedef uint32_t (*ParseFunc)(void *, uint8_t *, uint32_t, uint8_t); typedef uint32_t (*QueryFunc)(void *, void **); typedef uint32_t (*FlushFunc)(void *); typedef uint32_t (*UpdateFunc)(void *, void *, uint32_t, void **); void *mLibHandle; OpenFunc mParserOpen; CloseFunc mParserClose; ParseFunc mParserParse; QueryFunc mParserQuery; FlushFunc mParserFlush; UpdateFunc mParserUpdate; enum { // TODO: move this to vbp_loader.h VBP_INVALID = 0xFF, // TODO: move this to va.h VAProfileSoftwareDecoding = 0xFF, }; enum OUTPUT_METHOD { // output by Picture Coding Type (I, P, B) OUTPUT_BY_PCT, // output by Picture Order Count (for AVC only) OUTPUT_BY_POC, //OUTPUT_BY_POS, //OUTPUT_BY_PTS, }; private: bool mRawOutput; // whether to output NV12 raw data bool mManageReference; // this should stay true for VC1/MP4 decoder, and stay false for AVC decoder. AVC handles reference frame using DPB OUTPUT_METHOD mOutputMethod; int32_t mNumSurfaces; VideoSurfaceBuffer *mSurfaceBuffers; VideoSurfaceBuffer *mOutputHead; // head of output buffer list VideoSurfaceBuffer *mOutputTail; // tail of output buffer list VASurfaceID *mSurfaces; // surfaces array VASurfaceAttribExternalBuffers *mVASurfaceAttrib; uint8_t **mSurfaceUserPtr; // mapped user space pointer int32_t mSurfaceAcquirePos; // position of surface to start acquiring int32_t mNextOutputPOC; // Picture order count of next output _vbp_parser_type mParserType; void *mParserHandle; void *mSignalBufferPre[MAX_GRAPHIC_BUFFER_NUM]; uint32 mSignalBufferSize; bool mUseGEN; uint32_t mMetaDataBuffersNum; protected: void ManageReference(bool enable) {mManageReference = enable;} void setOutputMethod(OUTPUT_METHOD method) {mOutputMethod = method;} void setOutputWindowSize(int32_t size) {mOutputWindowSize = (size < OUTPUT_WINDOW_SIZE) ? size : OUTPUT_WINDOW_SIZE;} void querySurfaceRenderStatus(VideoSurfaceBuffer* surface); void enableLowDelayMode(bool enable) {mLowDelay = enable;} void setRotationDegrees(int32_t rotationDegrees); void setRenderRect(void); void setColorSpaceInfo(int32_t colorMatrix, int32_t videoRange); }; #endif // VIDEO_DECODER_BASE_H_