1/*
2* Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16
17#ifndef VIDEO_DECODER_BASE_H_
18#define VIDEO_DECODER_BASE_H_
19
20#include <va/va.h>
21#include <va/va_tpi.h>
22#include "VideoDecoderDefs.h"
23#include "VideoDecoderInterface.h"
24#include <pthread.h>
25#include <dlfcn.h>
26
27extern "C" {
28#include "vbp_loader.h"
29}
30
31#ifndef Display
32#ifdef USE_GEN_HW
33typedef char Display;
34#else
35typedef unsigned int Display;
36#endif
37#endif
38
39// TODO: check what is the best number. Must be at least 2 to support one backward reference frame.
40// Currently set to 8 to support 7 backward reference frames. This value is used for AVC frame reordering only.
41// e.g:
42// POC: 4P,  8P,  10P,  6B and mNextOutputPOC = 5
43#define OUTPUT_WINDOW_SIZE 8
44
45class VideoDecoderBase : public IVideoDecoder {
46public:
47    VideoDecoderBase(const char *mimeType, _vbp_parser_type type);
48    virtual ~VideoDecoderBase();
49
50    virtual Decode_Status start(VideoConfigBuffer *buffer);
51    virtual Decode_Status reset(VideoConfigBuffer *buffer) ;
52    virtual void stop(void);
53    //virtual Decode_Status decode(VideoDecodeBuffer *buffer);
54    virtual void flush(void);
55    virtual void freeSurfaceBuffers(void);
56    virtual const VideoRenderBuffer* getOutput(bool draining = false, VideoErrorBuffer *output_buf = NULL);
57    virtual Decode_Status signalRenderDone(void * graphichandler);
58    virtual const VideoFormatInfo* getFormatInfo(void);
59    virtual bool checkBufferAvail();
60    virtual void enableErrorReport(bool enabled = false) {mErrReportEnabled = enabled; };
61
62protected:
63    // each acquireSurfaceBuffer must be followed by a corresponding outputSurfaceBuffer or releaseSurfaceBuffer.
64    // Only one surface buffer can be acquired at any given time
65    virtual Decode_Status acquireSurfaceBuffer(void);
66    // frame is successfully decoded to the acquired surface buffer and surface is ready for output
67    virtual Decode_Status outputSurfaceBuffer(void);
68    // acquired surface  buffer is not used
69    virtual Decode_Status releaseSurfaceBuffer(void);
70    // flush all decoded but not rendered buffers
71    virtual void flushSurfaceBuffers(void);
72    virtual Decode_Status endDecodingFrame(bool dropFrame);
73    virtual VideoSurfaceBuffer* findOutputByPoc(bool draining = false);
74    virtual VideoSurfaceBuffer* findOutputByPct(bool draining = false);
75    virtual VideoSurfaceBuffer* findOutputByPts();
76    virtual Decode_Status setupVA(uint32_t numSurface, VAProfile profile, uint32_t numExtraSurface = 0);
77    virtual Decode_Status terminateVA(void);
78    virtual Decode_Status parseBuffer(uint8_t *buffer, int32_t size, bool config, void** vbpData);
79
80    static inline uint32_t alignMB(uint32_t a) {
81         return ((a + 15) & (~15));
82    }
83
84    virtual Decode_Status getRawDataFromSurface(VideoRenderBuffer *renderBuffer = NULL, uint8_t *pRawData = NULL, uint32_t *pSize = NULL, bool internal = true);
85
86#if (defined USE_AVC_SHORT_FORMAT) || (defined USE_SLICE_HEADER_PARSING)
87    Decode_Status updateBuffer(uint8_t *buffer, int32_t size, void** vbpData);
88    Decode_Status queryBuffer(void **vbpData);
89    Decode_Status setParserType(_vbp_parser_type type);
90    virtual Decode_Status getCodecSpecificConfigs(VAProfile profile, VAConfigID *config);
91#endif
92    virtual Decode_Status checkHardwareCapability();
93private:
94    Decode_Status mapSurface(void);
95    void initSurfaceBuffer(bool reset);
96    void drainDecodingErrors(VideoErrorBuffer *outErrBuf, VideoRenderBuffer *currentSurface);
97    void fillDecodingErrors(VideoRenderBuffer *currentSurface);
98
99    bool mInitialized;
100    pthread_mutex_t mLock;
101
102protected:
103    bool mLowDelay; // when true, decoded frame is immediately output for rendering
104    VideoFormatInfo mVideoFormatInfo;
105    Display *mDisplay;
106    VADisplay mVADisplay;
107    VAContextID mVAContext;
108    VAConfigID mVAConfig;
109    VASurfaceID *mExtraSurfaces; // extra surfaces array
110    int32_t mNumExtraSurfaces;
111    bool mVAStarted;
112    uint64_t mCurrentPTS; // current presentation time stamp (unit is unknown, depend on the framework: GStreamer 100-nanosec, Android: microsecond)
113    // the following three member variables should be set using
114    // acquireSurfaceBuffer/outputSurfaceBuffer/releaseSurfaceBuffer
115    VideoSurfaceBuffer *mAcquiredBuffer;
116    VideoSurfaceBuffer *mLastReference;
117    VideoSurfaceBuffer *mForwardReference;
118    VideoConfigBuffer  mConfigBuffer; // only store configure meta data.
119    bool mDecodingFrame; // indicate whether a frame is being decoded
120    bool mSizeChanged; // indicate whether video size is changed.
121    bool mShowFrame; // indicate whether the decoded frame is for display
122
123    int32_t mOutputWindowSize; // indicate limit of number of outstanding frames for output
124    int32_t mRotationDegrees;
125
126    bool mErrReportEnabled;
127    bool mWiDiOn;
128    typedef uint32_t (*OpenFunc)(uint32_t, void **);
129    typedef uint32_t (*CloseFunc)(void *);
130    typedef uint32_t (*ParseFunc)(void *, uint8_t *, uint32_t, uint8_t);
131    typedef uint32_t (*QueryFunc)(void *, void **);
132    typedef uint32_t (*FlushFunc)(void *);
133    typedef uint32_t (*UpdateFunc)(void *, void *, uint32_t, void **);
134    void *mLibHandle;
135    OpenFunc mParserOpen;
136    CloseFunc mParserClose;
137    ParseFunc mParserParse;
138    QueryFunc mParserQuery;
139    FlushFunc mParserFlush;
140    UpdateFunc mParserUpdate;
141    enum {
142        // TODO: move this to vbp_loader.h
143        VBP_INVALID = 0xFF,
144        // TODO: move this to va.h
145        VAProfileSoftwareDecoding = 0xFF,
146    };
147
148    enum OUTPUT_METHOD {
149        // output by Picture Coding Type (I, P, B)
150         OUTPUT_BY_PCT,
151        // output by Picture Order Count (for AVC only)
152         OUTPUT_BY_POC,
153         //OUTPUT_BY_POS,
154         //OUTPUT_BY_PTS,
155     };
156
157private:
158    bool mRawOutput; // whether to output NV12 raw data
159    bool mManageReference;  // this should stay true for VC1/MP4 decoder, and stay false for AVC decoder. AVC  handles reference frame using DPB
160    OUTPUT_METHOD mOutputMethod;
161
162    int32_t mNumSurfaces;
163    VideoSurfaceBuffer *mSurfaceBuffers;
164    VideoSurfaceBuffer *mOutputHead; // head of output buffer list
165    VideoSurfaceBuffer *mOutputTail;  // tail of output buffer list
166    VASurfaceID *mSurfaces; // surfaces array
167    VASurfaceAttribExternalBuffers *mVASurfaceAttrib;
168    uint8_t **mSurfaceUserPtr; // mapped user space pointer
169    int32_t mSurfaceAcquirePos; // position of surface to start acquiring
170    int32_t mNextOutputPOC; // Picture order count of next output
171    _vbp_parser_type mParserType;
172    void *mParserHandle;
173    void *mSignalBufferPre[MAX_GRAPHIC_BUFFER_NUM];
174    uint32 mSignalBufferSize;
175    bool mUseGEN;
176protected:
177    void ManageReference(bool enable) {mManageReference = enable;}
178    void setOutputMethod(OUTPUT_METHOD method) {mOutputMethod = method;}
179    void setOutputWindowSize(int32_t size) {mOutputWindowSize = (size < OUTPUT_WINDOW_SIZE) ? size : OUTPUT_WINDOW_SIZE;}
180    void querySurfaceRenderStatus(VideoSurfaceBuffer* surface);
181    void enableLowDelayMode(bool enable) {mLowDelay = enable;}
182    void setRotationDegrees(int32_t rotationDegrees);
183    void setRenderRect(void);
184};
185
186
187#endif  // VIDEO_DECODER_BASE_H_
188