1 /*
2 * Copyright 2019 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 #ifdef __LP64__
18 #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
19 #endif
20
21 //#define LOG_NDEBUG 0
22 #define LOG_TAG "Omx2IGraphicBufferSource"
23 #include <android-base/logging.h>
24
25 #include "Omx2IGraphicBufferSource.h"
26
27 #include <android/BnOMXBufferSource.h>
28 #include <media/OMXBuffer.h>
29 #include <media/stagefright/omx/OMXUtils.h>
30
31 #include <OMX_Component.h>
32 #include <OMX_Index.h>
33 #include <OMX_IndexExt.h>
34
35 namespace android {
36
37 namespace /* unnamed */ {
38
39 // OmxGraphicBufferSource -> IOMXBufferSource
40
41 struct OmxGbs2IOmxBs : public BnOMXBufferSource {
42 sp<OmxGraphicBufferSource> mBase;
OmxGbs2IOmxBsandroid::__anonfe6238880111::OmxGbs2IOmxBs43 OmxGbs2IOmxBs(sp<OmxGraphicBufferSource> const& base) : mBase{base} {}
onOmxExecutingandroid::__anonfe6238880111::OmxGbs2IOmxBs44 BnStatus onOmxExecuting() override {
45 return mBase->onOmxExecuting();
46 }
onOmxIdleandroid::__anonfe6238880111::OmxGbs2IOmxBs47 BnStatus onOmxIdle() override {
48 return mBase->onOmxIdle();
49 }
onOmxLoadedandroid::__anonfe6238880111::OmxGbs2IOmxBs50 BnStatus onOmxLoaded() override {
51 return mBase->onOmxLoaded();
52 }
onInputBufferAddedandroid::__anonfe6238880111::OmxGbs2IOmxBs53 BnStatus onInputBufferAdded(int32_t bufferId) override {
54 return mBase->onInputBufferAdded(bufferId);
55 }
onInputBufferEmptiedandroid::__anonfe6238880111::OmxGbs2IOmxBs56 BnStatus onInputBufferEmptied(
57 int32_t bufferId,
58 OMXFenceParcelable const& fenceParcel) override {
59 return mBase->onInputBufferEmptied(bufferId, fenceParcel.get());
60 }
61 };
62
63 struct OmxNodeWrapper : public IOmxNodeWrapper {
64 sp<IOMXNode> mBase;
OmxNodeWrapperandroid::__anonfe6238880111::OmxNodeWrapper65 OmxNodeWrapper(sp<IOMXNode> const& base) : mBase{base} {}
emptyBufferandroid::__anonfe6238880111::OmxNodeWrapper66 status_t emptyBuffer(
67 int32_t bufferId, uint32_t flags,
68 const sp<GraphicBuffer> &buffer,
69 int64_t timestamp, int fenceFd) override {
70 return mBase->emptyBuffer(bufferId, buffer, flags, timestamp, fenceFd);
71 }
dispatchDataSpaceChangedandroid::__anonfe6238880111::OmxNodeWrapper72 void dispatchDataSpaceChanged(
73 int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override {
74 omx_message msg{};
75 msg.type = omx_message::EVENT;
76 msg.fenceFd = -1;
77 msg.u.event_data.event = OMX_EventDataSpaceChanged;
78 msg.u.event_data.data1 = dataSpace;
79 msg.u.event_data.data2 = aspects;
80 msg.u.event_data.data3 = pixelFormat;
81 mBase->dispatchMessage(msg);
82 }
83 };
84
85 } // unnamed namespace
86
87 // Omx2IGraphicBufferSource
Omx2IGraphicBufferSource(sp<OmxGraphicBufferSource> const & base)88 Omx2IGraphicBufferSource::Omx2IGraphicBufferSource(
89 sp<OmxGraphicBufferSource> const& base)
90 : mBase{base},
91 mOMXBufferSource{new OmxGbs2IOmxBs(base)} {
92 }
93
setSuspend(bool suspend,int64_t timeUs)94 BnStatus Omx2IGraphicBufferSource::setSuspend(
95 bool suspend, int64_t timeUs) {
96 return BnStatus::fromStatusT(mBase->setSuspend(suspend, timeUs));
97 }
98
setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs)99 BnStatus Omx2IGraphicBufferSource::setRepeatPreviousFrameDelayUs(
100 int64_t repeatAfterUs) {
101 return BnStatus::fromStatusT(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
102 }
103
setMaxFps(float maxFps)104 BnStatus Omx2IGraphicBufferSource::setMaxFps(float maxFps) {
105 return BnStatus::fromStatusT(mBase->setMaxFps(maxFps));
106 }
107
setTimeLapseConfig(double fps,double captureFps)108 BnStatus Omx2IGraphicBufferSource::setTimeLapseConfig(
109 double fps, double captureFps) {
110 return BnStatus::fromStatusT(mBase->setTimeLapseConfig(fps, captureFps));
111 }
112
setStartTimeUs(int64_t startTimeUs)113 BnStatus Omx2IGraphicBufferSource::setStartTimeUs(
114 int64_t startTimeUs) {
115 return BnStatus::fromStatusT(mBase->setStartTimeUs(startTimeUs));
116 }
117
setStopTimeUs(int64_t stopTimeUs)118 BnStatus Omx2IGraphicBufferSource::setStopTimeUs(
119 int64_t stopTimeUs) {
120 return BnStatus::fromStatusT(mBase->setStopTimeUs(stopTimeUs));
121 }
122
getStopTimeOffsetUs(int64_t * stopTimeOffsetUs)123 BnStatus Omx2IGraphicBufferSource::getStopTimeOffsetUs(
124 int64_t *stopTimeOffsetUs) {
125 return BnStatus::fromStatusT(mBase->getStopTimeOffsetUs(stopTimeOffsetUs));
126 }
127
setColorAspects(int32_t aspects)128 BnStatus Omx2IGraphicBufferSource::setColorAspects(
129 int32_t aspects) {
130 return BnStatus::fromStatusT(mBase->setColorAspects(aspects));
131 }
132
setTimeOffsetUs(int64_t timeOffsetsUs)133 BnStatus Omx2IGraphicBufferSource::setTimeOffsetUs(
134 int64_t timeOffsetsUs) {
135 return BnStatus::fromStatusT(mBase->setTimeOffsetUs(timeOffsetsUs));
136 }
137
signalEndOfInputStream()138 BnStatus Omx2IGraphicBufferSource::signalEndOfInputStream() {
139 return BnStatus::fromStatusT(mBase->signalEndOfInputStream());
140 }
141
configure(const sp<IOMXNode> & omxNode,int32_t dataSpace)142 BnStatus Omx2IGraphicBufferSource::configure(
143 const sp<IOMXNode>& omxNode, int32_t dataSpace) {
144 if (omxNode == NULL) {
145 return BnStatus::fromServiceSpecificError(BAD_VALUE);
146 }
147
148 // Do setInputSurface() first, the node will try to enable metadata
149 // mode on input, and does necessary error checking. If this fails,
150 // we can't use this input surface on the node.
151 status_t err = omxNode->setInputSurface(mOMXBufferSource);
152 if (err != NO_ERROR) {
153 ALOGE("Unable to set input surface: %d", err);
154 return BnStatus::fromServiceSpecificError(err);
155 }
156
157 uint32_t consumerUsage;
158 if (omxNode->getParameter(
159 (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
160 &consumerUsage, sizeof(consumerUsage)) != OK) {
161 consumerUsage = 0;
162 }
163
164 OMX_PARAM_PORTDEFINITIONTYPE def;
165 InitOMXParams(&def);
166 def.nPortIndex = 0; // kPortIndexInput
167
168 err = omxNode->getParameter(
169 OMX_IndexParamPortDefinition, &def, sizeof(def));
170 if (err != NO_ERROR) {
171 ALOGE("Failed to get port definition: %d", err);
172 return BnStatus::fromServiceSpecificError(UNKNOWN_ERROR);
173 }
174
175 return BnStatus::fromStatusT(mBase->configure(
176 new OmxNodeWrapper(omxNode),
177 dataSpace,
178 def.nBufferCountActual,
179 def.format.video.nFrameWidth,
180 def.format.video.nFrameHeight,
181 consumerUsage));
182 }
183
184 } // namespace android
185
186