summaryrefslogtreecommitdiffstats
path: root/camera/inc/OmxFrameDecoder.h
blob: 7cbbf2c1f6559787e3e79cc04e3f83f1394c9762 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/*
 * Copyright (C) Texas Instruments - http://www.ti.com/
 *
 * 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 OMXFRAMEDECODER_H_
#define OMXFRAMEDECODER_H_


#include <utils/threads.h>
#include <utils/List.h>
#include "FrameDecoder.h"
#include "OMX_Types.h"
#include "OMX_Core.h"
#include "OMX_Component.h"
#include "Decoder_libjpeg.h"

namespace Ti {
namespace Camera {

enum OmxDecoderState {
    OmxDecoderState_Unloaded = 0,
    OmxDecoderState_Loaded,
    OmxDecoderState_Idle,
    OmxDecoderState_Executing,
    OmxDecoderState_Error,
    OmxDecoderState_Invalid,
    OmxDecoderState_Reconfigure,
    OmxDecoderState_Exit
};

enum PortType {
    PortIndexInput  = 0,
    PortIndexOutput = 1
};


struct OmxMessage {
    enum {
        EVENT,
        EMPTY_BUFFER_DONE,
        FILL_BUFFER_DONE,
    }type;

    union {
        // if type == EVENT
        struct {
            OMX_PTR appData;
            OMX_EVENTTYPE event;
            OMX_U32 data1;
            OMX_U32 data2;
            OMX_PTR pEventData;
        } eventData;

        // if type == (EMPTY_BUFFER_DONE || FILL_BUFFER_DONE)
        struct {
            OMX_PTR appData;
            OMX_BUFFERHEADERTYPE* pBuffHead;
        } bufferData;
    } u;
};

class CallbackDispatcher;

struct CallbackDispatcherThread : public android::Thread {
    CallbackDispatcherThread(CallbackDispatcher *dispatcher)
        : mDispatcher(dispatcher) {
    }

private:
    CallbackDispatcher *mDispatcher;

    bool threadLoop();

    CallbackDispatcherThread(const CallbackDispatcherThread &);
    CallbackDispatcherThread &operator=(const CallbackDispatcherThread &);
};

class CallbackDispatcher
{

public:
    CallbackDispatcher();
    ~CallbackDispatcher();

    void post(const OmxMessage &msg);
    bool loop();

private:
    void dispatch(const OmxMessage &msg);

    CallbackDispatcher(const CallbackDispatcher &);
    CallbackDispatcher &operator=(const CallbackDispatcher &);

    android::Mutex mLock;
    android::Condition mQueueChanged;
    android::List<OmxMessage> mQueue;
    android::sp<CallbackDispatcherThread> mThread;
    bool mDone;
};

class OmxFrameDecoder : public FrameDecoder
{

public:
    OmxFrameDecoder(DecoderType type = DecoderType_MJPEG);
    virtual ~OmxFrameDecoder();

    OMX_ERRORTYPE eventHandler(const OMX_EVENTTYPE event, const OMX_U32 data1, const OMX_U32 data2,
                const OMX_PTR pEventData);
    OMX_ERRORTYPE fillBufferDoneHandler(OMX_BUFFERHEADERTYPE* pBuffHead);
    OMX_ERRORTYPE emptyBufferDoneHandler(OMX_BUFFERHEADERTYPE* pBuffHead);

    static OMX_ERRORTYPE eventCallback(const OMX_HANDLETYPE component,
                const OMX_PTR appData, const OMX_EVENTTYPE event, const OMX_U32 data1, const OMX_U32 data2,
                const OMX_PTR pEventData);
    static OMX_ERRORTYPE emptyBufferDoneCallback(OMX_HANDLETYPE hComponent, OMX_PTR appData, OMX_BUFFERHEADERTYPE* pBuffHead);
    static OMX_ERRORTYPE fillBufferDoneCallback(OMX_HANDLETYPE hComponent, OMX_PTR appData, OMX_BUFFERHEADERTYPE* pBuffHead);

    virtual bool getPaddedDimensions(size_t &width, size_t &height);

protected:
    virtual void doConfigure (const DecoderParameters& config);
    virtual void doProcessInputBuffer();
    virtual status_t doStart();
    virtual void doStop();
    virtual void doFlush();
    virtual void doRelease();

private:
    status_t setComponentRole();
    status_t enableGrallockHandles();
    status_t allocateBuffersOutput();
    void freeBuffersOnOutput();
    void freeBuffersOnInput();
    status_t doPortReconfigure();
    void dumpPortSettings(PortType port);
    status_t getAndConfigureDecoder();
    status_t configureJpegPorts(int width, int height);
    status_t switchToIdle();
    status_t allocateBuffersInput();
    status_t disablePortSync(int port);
    status_t enablePortSync(int port);
    void queueOutputBuffers();
    status_t setVideoOutputFormat(OMX_U32 width, OMX_U32 height);


    status_t omxInit();
    status_t omxGetHandle(OMX_HANDLETYPE *handle, OMX_PTR pAppData, OMX_CALLBACKTYPE & callbacks);
    OmxDecoderState getOmxState() { return mCurrentState; }
    status_t commitState(OmxDecoderState state) { mPreviousState = mCurrentState; mCurrentState = state; return NO_ERROR; }
    status_t setVideoPortFormatType(
            OMX_U32 portIndex,
            OMX_VIDEO_CODINGTYPE compressionFormat,
            OMX_COLOR_FORMATTYPE colorFormat);
    status_t omxGetParameter(OMX_INDEXTYPE index, OMX_PTR ptr);
    status_t omxSetParameter(OMX_INDEXTYPE index, OMX_PTR ptr);
    status_t omxSendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param);
    status_t omxGetConfig(OMX_INDEXTYPE index, OMX_PTR ptr);
    status_t omxSetConfig(OMX_INDEXTYPE index, OMX_PTR ptr);
    status_t omxFillThisBuffer(OMX_BUFFERHEADERTYPE *pOutBufHdr);
    status_t omxEmptyThisBuffer(android::sp<MediaBuffer>& inBuffer, OMX_BUFFERHEADERTYPE *pInBufHdr);
    void omxDumpPortSettings(OMX_PARAM_PORTDEFINITIONTYPE& def);
    void omxDumpBufferHeader (OMX_BUFFERHEADERTYPE* bh);
    status_t omxSwitchToExecutingSync();

    bool mOmxInialized;

    OMX_HANDLETYPE mHandleComp;
    OmxDecoderState mCurrentState;
    OmxDecoderState mPreviousState;

    // Condition and Mutex used during OpenMAX state transitions & command completion
    android::Condition mStateCondition;
    android::Mutex mHwLock;

    android::Vector<OMX_BUFFERHEADERTYPE*> mOutBufferHeaders;
    android::Vector<OMX_BUFFERHEADERTYPE*> mInBufferHeaders;

    CallbackDispatcher mDispatcher;

    bool mStopping;
    DecoderType mDecoderType;

    // If true we will search for DHT in JPEG buffer
    bool mIsNeedCheckDHT;
    // If true we always append DHT to JPEG buffer
    bool mAlwaysAppendDHT;
};

} //namespace Camera
} //namespace Ti
#endif /* OMXFRAMEDECODER_H_ */