1/*
2 * Copyright 2017, 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//#define LOG_NDEBUG 0
18#define LOG_TAG "BWGraphicBufferSource"
19
20#include <OMX_Component.h>
21#include <OMX_IndexExt.h>
22
23#include <media/OMXBuffer.h>
24#include <IOMX.h>
25
26#include "OMXUtils.h"
27#include "BWGraphicBufferSource.h"
28
29namespace android {
30
31static const OMX_U32 kPortIndexInput = 0;
32
33struct BWGraphicBufferSource::BWOmxNodeWrapper : public IOmxNodeWrapper {
34    sp<IOMXNode> mOMXNode;
35
36    BWOmxNodeWrapper(const sp<IOMXNode> &omxNode): mOMXNode(omxNode) {
37    }
38
39    virtual status_t emptyBuffer(
40            int32_t bufferId, uint32_t flags,
41            const sp<GraphicBuffer> &buffer,
42            int64_t timestamp, int fenceFd) override {
43        return mOMXNode->emptyBuffer(bufferId, buffer, flags, timestamp, fenceFd);
44    }
45
46    virtual void dispatchDataSpaceChanged(
47            int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override {
48        omx_message msg;
49        msg.type = omx_message::EVENT;
50        msg.fenceFd = -1;
51        msg.u.event_data.event = OMX_EventDataSpaceChanged;
52        msg.u.event_data.data1 = dataSpace;
53        msg.u.event_data.data2 = aspects;
54        msg.u.event_data.data3 = pixelFormat;
55        mOMXNode->dispatchMessage(msg);
56    }
57};
58
59struct BWGraphicBufferSource::BWOMXBufferSource : public BnOMXBufferSource {
60    sp<GraphicBufferSource> mSource;
61
62    BWOMXBufferSource(const sp<GraphicBufferSource> &source): mSource(source) {
63    }
64
65    Status onOmxExecuting() override {
66        return mSource->onOmxExecuting();
67    }
68
69    Status onOmxIdle() override {
70        return mSource->onOmxIdle();
71    }
72
73    Status onOmxLoaded() override {
74        return mSource->onOmxLoaded();
75    }
76
77    Status onInputBufferAdded(int bufferId) override {
78        return mSource->onInputBufferAdded(bufferId);
79    }
80
81    Status onInputBufferEmptied(
82            int bufferId, const OMXFenceParcelable& fenceParcel) override {
83        return mSource->onInputBufferEmptied(bufferId, fenceParcel.get());
84    }
85};
86
87BWGraphicBufferSource::BWGraphicBufferSource(
88        sp<GraphicBufferSource> const& base) :
89    mBase(base),
90    mOMXBufferSource(new BWOMXBufferSource(base)) {
91}
92
93::android::binder::Status BWGraphicBufferSource::configure(
94        const sp<IOMXNode>& omxNode, int32_t dataSpace) {
95    // Do setInputSurface() first, the node will try to enable metadata
96    // mode on input, and does necessary error checking. If this fails,
97    // we can't use this input surface on the node.
98    status_t err = omxNode->setInputSurface(mOMXBufferSource);
99    if (err != NO_ERROR) {
100        ALOGE("Unable to set input surface: %d", err);
101        return Status::fromStatusT(err);
102    }
103
104    // use consumer usage bits queried from encoder, but always add
105    // HW_VIDEO_ENCODER for backward compatibility.
106    uint32_t consumerUsage;
107    if (omxNode->getParameter(
108            (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
109            &consumerUsage, sizeof(consumerUsage)) != OK) {
110        consumerUsage = 0;
111    }
112
113    OMX_PARAM_PORTDEFINITIONTYPE def;
114    InitOMXParams(&def);
115    def.nPortIndex = kPortIndexInput;
116
117    err = omxNode->getParameter(
118            OMX_IndexParamPortDefinition, &def, sizeof(def));
119    if (err != NO_ERROR) {
120        ALOGE("Failed to get port definition: %d", err);
121        return Status::fromStatusT(UNKNOWN_ERROR);
122    }
123
124    return Status::fromStatusT(mBase->configure(
125              new BWOmxNodeWrapper(omxNode),
126              dataSpace,
127              def.nBufferCountActual,
128              def.format.video.nFrameWidth,
129              def.format.video.nFrameHeight,
130              consumerUsage));
131}
132
133::android::binder::Status BWGraphicBufferSource::setSuspend(
134        bool suspend, int64_t timeUs) {
135    return Status::fromStatusT(mBase->setSuspend(suspend, timeUs));
136}
137
138::android::binder::Status BWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
139        int64_t repeatAfterUs) {
140    return Status::fromStatusT(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
141}
142
143::android::binder::Status BWGraphicBufferSource::setMaxFps(float maxFps) {
144    return Status::fromStatusT(mBase->setMaxFps(maxFps));
145}
146
147::android::binder::Status BWGraphicBufferSource::setTimeLapseConfig(
148        double fps, double captureFps) {
149    return Status::fromStatusT(mBase->setTimeLapseConfig(
150            fps, captureFps));
151}
152
153::android::binder::Status BWGraphicBufferSource::setStartTimeUs(
154        int64_t startTimeUs) {
155    return Status::fromStatusT(mBase->setStartTimeUs(startTimeUs));
156}
157
158::android::binder::Status BWGraphicBufferSource::setStopTimeUs(
159        int64_t stopTimeUs) {
160    return Status::fromStatusT(mBase->setStopTimeUs(stopTimeUs));
161}
162
163::android::binder::Status BWGraphicBufferSource::setColorAspects(
164        int32_t aspects) {
165    return Status::fromStatusT(mBase->setColorAspects(aspects));
166}
167
168::android::binder::Status BWGraphicBufferSource::setTimeOffsetUs(
169        int64_t timeOffsetsUs) {
170    return Status::fromStatusT(mBase->setTimeOffsetUs(timeOffsetsUs));
171}
172
173::android::binder::Status BWGraphicBufferSource::signalEndOfInputStream() {
174    return Status::fromStatusT(mBase->signalEndOfInputStream());
175}
176
177}  // namespace android
178