1d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih/*
2d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih * Copyright 2017, The Android Open Source Project
3d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih *
4d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih * Licensed under the Apache License, Version 2.0 (the "License");
5d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih * you may not use this file except in compliance with the License.
6d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih * You may obtain a copy of the License at
7d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih *
8d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih *      http://www.apache.org/licenses/LICENSE-2.0
9d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih *
10d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih * Unless required by applicable law or agreed to in writing, software
11d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih * distributed under the License is distributed on an "AS IS" BASIS,
12d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih * See the License for the specific language governing permissions and
14d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih * limitations under the License.
15d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih */
16d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
17d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih//#define LOG_NDEBUG 0
18d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih#define LOG_TAG "BWGraphicBufferSource"
19d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
20255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/stagefright/omx/BWGraphicBufferSource.h>
21255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/stagefright/omx/OMXUtils.h>
22255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/openmax/OMX_Component.h>
23255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/openmax/OMX_IndexExt.h>
24d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih#include <media/OMXBuffer.h>
25eeb436397a78aa80e41a4929a5f379319eefe0c3Colin Cross#include <media/IOMX.h>
26d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
27d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihnamespace android {
28d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
29d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatic const OMX_U32 kPortIndexInput = 0;
30d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
31d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstruct BWGraphicBufferSource::BWOmxNodeWrapper : public IOmxNodeWrapper {
32d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    sp<IOMXNode> mOMXNode;
33d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
34d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    BWOmxNodeWrapper(const sp<IOMXNode> &omxNode): mOMXNode(omxNode) {
35d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
36d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
37d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    virtual status_t emptyBuffer(
38d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            int32_t bufferId, uint32_t flags,
39d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            const sp<GraphicBuffer> &buffer,
40d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            int64_t timestamp, int fenceFd) override {
41d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return mOMXNode->emptyBuffer(bufferId, buffer, flags, timestamp, fenceFd);
42d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
43d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
44d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    virtual void dispatchDataSpaceChanged(
45d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override {
46d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        omx_message msg;
47d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        msg.type = omx_message::EVENT;
48d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        msg.fenceFd = -1;
49d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        msg.u.event_data.event = OMX_EventDataSpaceChanged;
50d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        msg.u.event_data.data1 = dataSpace;
51d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        msg.u.event_data.data2 = aspects;
52d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        msg.u.event_data.data3 = pixelFormat;
53d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        mOMXNode->dispatchMessage(msg);
54d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
55d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih};
56d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
57d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstruct BWGraphicBufferSource::BWOMXBufferSource : public BnOMXBufferSource {
582860573684ebaf514827cc1b5b144deb194eb8f6Wonsik Kim    sp<OmxGraphicBufferSource> mSource;
59d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
602860573684ebaf514827cc1b5b144deb194eb8f6Wonsik Kim    BWOMXBufferSource(const sp<OmxGraphicBufferSource> &source): mSource(source) {
61d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
62d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
63d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    Status onOmxExecuting() override {
64d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return mSource->onOmxExecuting();
65d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
66d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
67d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    Status onOmxIdle() override {
68d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return mSource->onOmxIdle();
69d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
70d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
71d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    Status onOmxLoaded() override {
72d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return mSource->onOmxLoaded();
73d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
74d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
75d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    Status onInputBufferAdded(int bufferId) override {
76d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return mSource->onInputBufferAdded(bufferId);
77d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
78d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
79d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    Status onInputBufferEmptied(
80d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            int bufferId, const OMXFenceParcelable& fenceParcel) override {
81d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return mSource->onInputBufferEmptied(bufferId, fenceParcel.get());
82d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
83d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih};
84d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
85d095e65c8c125c555046c60539a0f7abf0ccf271Robert ShihBWGraphicBufferSource::BWGraphicBufferSource(
862860573684ebaf514827cc1b5b144deb194eb8f6Wonsik Kim        sp<OmxGraphicBufferSource> const& base) :
87d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    mBase(base),
88d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    mOMXBufferSource(new BWOMXBufferSource(base)) {
89d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih}
90d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
91d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih::android::binder::Status BWGraphicBufferSource::configure(
92d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        const sp<IOMXNode>& omxNode, int32_t dataSpace) {
93d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    // Do setInputSurface() first, the node will try to enable metadata
94d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    // mode on input, and does necessary error checking. If this fails,
95d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    // we can't use this input surface on the node.
96d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    status_t err = omxNode->setInputSurface(mOMXBufferSource);
97d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    if (err != NO_ERROR) {
98d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        ALOGE("Unable to set input surface: %d", err);
99d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return Status::fromStatusT(err);
100d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
101d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
102d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    // use consumer usage bits queried from encoder, but always add
103d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    // HW_VIDEO_ENCODER for backward compatibility.
104d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    uint32_t consumerUsage;
105d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    if (omxNode->getParameter(
106d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
107d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            &consumerUsage, sizeof(consumerUsage)) != OK) {
108d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        consumerUsage = 0;
109d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
110d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
111d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    OMX_PARAM_PORTDEFINITIONTYPE def;
112d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    InitOMXParams(&def);
113d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    def.nPortIndex = kPortIndexInput;
114d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
115d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    err = omxNode->getParameter(
116d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            OMX_IndexParamPortDefinition, &def, sizeof(def));
117d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    if (err != NO_ERROR) {
118d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        ALOGE("Failed to get port definition: %d", err);
119d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return Status::fromStatusT(UNKNOWN_ERROR);
120d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
121d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
122d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return Status::fromStatusT(mBase->configure(
123d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih              new BWOmxNodeWrapper(omxNode),
124d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih              dataSpace,
125d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih              def.nBufferCountActual,
126d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih              def.format.video.nFrameWidth,
127d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih              def.format.video.nFrameHeight,
128d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih              consumerUsage));
129d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih}
130d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
131d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih::android::binder::Status BWGraphicBufferSource::setSuspend(
132d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        bool suspend, int64_t timeUs) {
133d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return Status::fromStatusT(mBase->setSuspend(suspend, timeUs));
134d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih}
135d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
136d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih::android::binder::Status BWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
137d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        int64_t repeatAfterUs) {
138d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return Status::fromStatusT(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
139d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih}
140d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
141d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih::android::binder::Status BWGraphicBufferSource::setMaxFps(float maxFps) {
142d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return Status::fromStatusT(mBase->setMaxFps(maxFps));
143d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih}
144d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
145d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih::android::binder::Status BWGraphicBufferSource::setTimeLapseConfig(
14622dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        double fps, double captureFps) {
147d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return Status::fromStatusT(mBase->setTimeLapseConfig(
14822dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            fps, captureFps));
149d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih}
150d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
151d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih::android::binder::Status BWGraphicBufferSource::setStartTimeUs(
152d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        int64_t startTimeUs) {
153d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return Status::fromStatusT(mBase->setStartTimeUs(startTimeUs));
154d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih}
155d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
156d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih::android::binder::Status BWGraphicBufferSource::setStopTimeUs(
157d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        int64_t stopTimeUs) {
158d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return Status::fromStatusT(mBase->setStopTimeUs(stopTimeUs));
159d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih}
160d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
161f72cefddf378909f360998852e41f49042711299Hangyu Kuang::android::binder::Status BWGraphicBufferSource::getStopTimeOffsetUs(
162f72cefddf378909f360998852e41f49042711299Hangyu Kuang        int64_t *stopTimeOffsetUs) {
163f72cefddf378909f360998852e41f49042711299Hangyu Kuang    return Status::fromStatusT(mBase->getStopTimeOffsetUs(stopTimeOffsetUs));
164f72cefddf378909f360998852e41f49042711299Hangyu Kuang}
165f72cefddf378909f360998852e41f49042711299Hangyu Kuang
166d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih::android::binder::Status BWGraphicBufferSource::setColorAspects(
167d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        int32_t aspects) {
168d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return Status::fromStatusT(mBase->setColorAspects(aspects));
169d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih}
170d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
171d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih::android::binder::Status BWGraphicBufferSource::setTimeOffsetUs(
172d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        int64_t timeOffsetsUs) {
173d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return Status::fromStatusT(mBase->setTimeOffsetUs(timeOffsetsUs));
174d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih}
175d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
176d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih::android::binder::Status BWGraphicBufferSource::signalEndOfInputStream() {
177d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return Status::fromStatusT(mBase->signalEndOfInputStream());
178d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih}
179d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
180d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih}  // namespace android
181