1 /*
2  * Copyright (C) 2013 The Android Open Source Project
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 SOFT_VIDEO_DECODER_OMX_COMPONENT_H_
18 
19 #define SOFT_VIDEO_DECODER_OMX_COMPONENT_H_
20 
21 #include "SimpleSoftOMXComponent.h"
22 
23 #include <media/stagefright/foundation/ABuffer.h>
24 #include <media/stagefright/foundation/AHandlerReflector.h>
25 #include <media/stagefright/foundation/ColorUtils.h>
26 #include <media/openmax/OMX_Core.h>
27 #include <media/openmax/OMX_Video.h>
28 #include <media/openmax/OMX_VideoExt.h>
29 
30 #include <media/hardware/HardwareAPI.h>
31 
32 #include <utils/RefBase.h>
33 #include <utils/threads.h>
34 #include <utils/Vector.h>
35 #include <utils/List.h>
36 
37 namespace android {
38 
39 struct SoftVideoDecoderOMXComponent : public SimpleSoftOMXComponent {
40     SoftVideoDecoderOMXComponent(
41             const char *name,
42             const char *componentRole,
43             OMX_VIDEO_CODINGTYPE codingType,
44             const CodecProfileLevel *profileLevels,
45             size_t numProfileLevels,
46             int32_t width,
47             int32_t height,
48             const OMX_CALLBACKTYPE *callbacks,
49             OMX_PTR appData,
50             OMX_COMPONENTTYPE **component);
51 
52 protected:
53     enum {
54         kDescribeColorAspectsIndex = kPrepareForAdaptivePlaybackIndex + 1,
55         kDescribeHdrStaticInfoIndex = kPrepareForAdaptivePlaybackIndex + 2,
56         kDescribeHdr10PlusInfoIndex = kPrepareForAdaptivePlaybackIndex + 3,
57     };
58 
59     enum {
60         kNotSupported,
61         kPreferBitstream,
62         kPreferContainer,
63     };
64 
65     virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled);
66     virtual void onReset();
67 
68     virtual OMX_ERRORTYPE internalGetParameter(
69             OMX_INDEXTYPE index, OMX_PTR params);
70 
71     virtual OMX_ERRORTYPE internalSetParameter(
72             OMX_INDEXTYPE index, const OMX_PTR params);
73 
74     virtual OMX_ERRORTYPE getConfig(
75             OMX_INDEXTYPE index, OMX_PTR params);
76 
77     virtual OMX_ERRORTYPE internalSetConfig(
78             OMX_INDEXTYPE index, const OMX_PTR params, bool *frameConfig);
79 
80     virtual OMX_ERRORTYPE getExtensionIndex(
81             const char *name, OMX_INDEXTYPE *index);
82 
83     virtual bool supportsDescribeColorAspects();
84 
85     virtual int getColorAspectPreference();
86 
87     virtual bool supportDescribeHdrStaticInfo();
88 
89     virtual bool supportDescribeHdr10PlusInfo();
90 
91     // This function sets both minimum buffer count and actual buffer count of
92     // input port to be |numInputBuffers|. It will also set both minimum buffer
93     // count and actual buffer count of output port to be |numOutputBuffers|.
94     void initPorts(OMX_U32 numInputBuffers,
95             OMX_U32 inputBufferSize,
96             OMX_U32 numOutputBuffers,
97             const char *mimeType,
98             OMX_U32 minCompressionRatio = 1u);
99 
100     // This function sets input port's minimum buffer count to |numMinInputBuffers|,
101     // sets input port's actual buffer count to |numInputBuffers|, sets output port's
102     // minimum buffer count to |numMinOutputBuffers| and sets output port's actual buffer
103     // count to be |numOutputBuffers|.
104     void initPorts(OMX_U32 numMinInputBuffers,
105             OMX_U32 numInputBuffers,
106             OMX_U32 inputBufferSize,
107             OMX_U32 numMinOutputBuffers,
108             OMX_U32 numOutputBuffers,
109             const char *mimeType,
110             OMX_U32 minCompressionRatio = 1u);
111 
112     virtual void updatePortDefinitions(bool updateCrop = true, bool updateInputSize = false);
113 
114     uint32_t outputBufferWidth();
115     uint32_t outputBufferHeight();
116 
117     enum CropSettingsMode {
118         kCropUnSet = 0,
119         kCropSet,
120         kCropChanged,
121     };
122 
123     // This function will handle several port change events which include
124     // size changed, crop changed, stride changed and coloraspects changed.
125     // It will trigger OMX_EventPortSettingsChanged event if necessary.
126     void handlePortSettingsChange(
127             bool *portWillReset, uint32_t width, uint32_t height,
128             OMX_COLOR_FORMATTYPE outputFormat = OMX_COLOR_FormatYUV420Planar,
129             CropSettingsMode cropSettingsMode = kCropUnSet,
130             bool fakeStride = false);
131 
132     void copyYV12FrameToOutputBuffer(
133             uint8_t *dst, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
134             size_t srcYStride, size_t srcUStride, size_t srcVStride);
135 
136     enum {
137         kInputPortIndex  = 0,
138         kOutputPortIndex = 1,
139         kMaxPortIndex = 1,
140     };
141 
142     bool mIsAdaptive;
143     uint32_t mAdaptiveMaxWidth, mAdaptiveMaxHeight;
144     uint32_t mWidth, mHeight;
145     uint32_t mCropLeft, mCropTop, mCropWidth, mCropHeight;
146     OMX_COLOR_FORMATTYPE mOutputFormat;
147     HDRStaticInfo mHdrStaticInfo;
148     enum {
149         NONE,
150         AWAITING_DISABLED,
151         AWAITING_ENABLED
152     } mOutputPortSettingsChange;
153 
154     bool mUpdateColorAspects;
155 
156     Mutex mColorAspectsLock;
157     // color aspects passed from the framework.
158     ColorAspects mDefaultColorAspects;
159     // color aspects parsed from the bitstream.
160     ColorAspects mBitstreamColorAspects;
161     // final color aspects after combining the above two aspects.
162     ColorAspects mFinalColorAspects;
163 
164     bool colorAspectsDiffer(const ColorAspects &a, const ColorAspects &b);
165 
166     // This functions takes two color aspects and updates the mFinalColorAspects
167     // based on |preferredAspects|.
168     void updateFinalColorAspects(
169             const ColorAspects &otherAspects, const ColorAspects &preferredAspects);
170 
171     // This function will update the mFinalColorAspects based on codec preference.
172     status_t handleColorAspectsChange();
173 
174     // Helper function to dump the ColorAspects.
175     void dumpColorAspects(const ColorAspects &colorAspects);
176 
177     sp<ABuffer> dequeueInputFrameConfig();
178     void queueOutputFrameConfig(const sp<ABuffer> &info);
179 
180 private:
181     uint32_t mMinInputBufferSize;
182     uint32_t mMinCompressionRatio;
183 
184     const char *mComponentRole;
185     OMX_VIDEO_CODINGTYPE mCodingType;
186     const CodecProfileLevel *mProfileLevels;
187     size_t mNumProfileLevels;
188     typedef List<sp<ABuffer> > Hdr10PlusInfoList;
189     Hdr10PlusInfoList mHdr10PlusInputs;
190     Hdr10PlusInfoList mHdr10PlusOutputs;
191 
192     DISALLOW_EVIL_CONSTRUCTORS(SoftVideoDecoderOMXComponent);
193 };
194 
195 }  // namespace android
196 
197 #endif  // SOFT_VIDEO_DECODER_OMX_COMPONENT_H_
198