blob: 764fa001ecc149b4ab504d15df11bc5602330d78 [file] [log] [blame]
Winson Chiu47eaa192019-10-24 01:14:51 +00001/*
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
35namespace android {
36
37namespace /* unnamed */ {
38
39// OmxGraphicBufferSource -> IOMXBufferSource
40
41struct OmxGbs2IOmxBs : public BnOMXBufferSource {
42 sp<OmxGraphicBufferSource> mBase;
43 OmxGbs2IOmxBs(sp<OmxGraphicBufferSource> const& base) : mBase{base} {}
44 BnStatus onOmxExecuting() override {
45 return mBase->onOmxExecuting();
46 }
47 BnStatus onOmxIdle() override {
48 return mBase->onOmxIdle();
49 }
50 BnStatus onOmxLoaded() override {
51 return mBase->onOmxLoaded();
52 }
53 BnStatus onInputBufferAdded(int32_t bufferId) override {
54 return mBase->onInputBufferAdded(bufferId);
55 }
56 BnStatus onInputBufferEmptied(
57 int32_t bufferId,
58 OMXFenceParcelable const& fenceParcel) override {
59 return mBase->onInputBufferEmptied(bufferId, fenceParcel.get());
60 }
61};
62
63struct OmxNodeWrapper : public IOmxNodeWrapper {
64 sp<IOMXNode> mBase;
65 OmxNodeWrapper(sp<IOMXNode> const& base) : mBase{base} {}
66 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 }
72 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
88Omx2IGraphicBufferSource::Omx2IGraphicBufferSource(
89 sp<OmxGraphicBufferSource> const& base)
90 : mBase{base},
91 mOMXBufferSource{new OmxGbs2IOmxBs(base)} {
92}
93
94BnStatus Omx2IGraphicBufferSource::setSuspend(
95 bool suspend, int64_t timeUs) {
96 return BnStatus::fromStatusT(mBase->setSuspend(suspend, timeUs));
97}
98
99BnStatus Omx2IGraphicBufferSource::setRepeatPreviousFrameDelayUs(
100 int64_t repeatAfterUs) {
101 return BnStatus::fromStatusT(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
102}
103
104BnStatus Omx2IGraphicBufferSource::setMaxFps(float maxFps) {
105 return BnStatus::fromStatusT(mBase->setMaxFps(maxFps));
106}
107
108BnStatus Omx2IGraphicBufferSource::setTimeLapseConfig(
109 double fps, double captureFps) {
110 return BnStatus::fromStatusT(mBase->setTimeLapseConfig(fps, captureFps));
111}
112
113BnStatus Omx2IGraphicBufferSource::setStartTimeUs(
114 int64_t startTimeUs) {
115 return BnStatus::fromStatusT(mBase->setStartTimeUs(startTimeUs));
116}
117
118BnStatus Omx2IGraphicBufferSource::setStopTimeUs(
119 int64_t stopTimeUs) {
120 return BnStatus::fromStatusT(mBase->setStopTimeUs(stopTimeUs));
121}
122
123BnStatus Omx2IGraphicBufferSource::getStopTimeOffsetUs(
124 int64_t *stopTimeOffsetUs) {
125 return BnStatus::fromStatusT(mBase->getStopTimeOffsetUs(stopTimeOffsetUs));
126}
127
128BnStatus Omx2IGraphicBufferSource::setColorAspects(
129 int32_t aspects) {
130 return BnStatus::fromStatusT(mBase->setColorAspects(aspects));
131}
132
133BnStatus Omx2IGraphicBufferSource::setTimeOffsetUs(
134 int64_t timeOffsetsUs) {
135 return BnStatus::fromStatusT(mBase->setTimeOffsetUs(timeOffsetsUs));
136}
137
138BnStatus Omx2IGraphicBufferSource::signalEndOfInputStream() {
139 return BnStatus::fromStatusT(mBase->signalEndOfInputStream());
140}
141
142BnStatus 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