1f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa/*
2f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * Copyright 2016, The Android Open Source Project
3f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
4f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * Licensed under the Apache License, Version 2.0 (the "License");
5f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * you may not use this file except in compliance with the License.
6f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * You may obtain a copy of the License at
7f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
8f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *      http://www.apache.org/licenses/LICENSE-2.0
9f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa *
10f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * Unless required by applicable law or agreed to in writing, software
11f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * distributed under the License is distributed on an "AS IS" BASIS,
12f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * See the License for the specific language governing permissions and
14f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa * limitations under the License.
15f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa */
16f62ea8018813951e8f6a182880cadb3217e4ce37Pawin Vongmasa
17d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih//#define LOG_NDEBUG 0
18d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih#define LOG_TAG "TWGraphicBufferSource"
190d3a5edf232916e81adbc46fc0f4a1753166b066Pawin Vongmasa
20d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih#include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
21d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih#include <android/hardware/media/omx/1.0/IOmxNode.h>
22d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih#include <OMX_Component.h>
23d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih#include <OMX_IndexExt.h>
24d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
25d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih#include "omx/OMXUtils.h"
26517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#include "WGraphicBufferSource.h"
27517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa#include "WOmxNode.h"
280d3a5edf232916e81adbc46fc0f4a1753166b066Pawin Vongmasa#include "Conversion.h"
29517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
30517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasanamespace android {
31517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasanamespace hardware {
32517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasanamespace media {
33517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasanamespace omx {
34517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasanamespace V1_0 {
35517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasanamespace implementation {
36517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
37d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstatic const OMX_U32 kPortIndexInput = 0;
38d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
39d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstruct TWGraphicBufferSource::TWOmxNodeWrapper : public IOmxNodeWrapper {
40d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    sp<IOmxNode> mOmxNode;
41d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
42d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    TWOmxNodeWrapper(const sp<IOmxNode> &omxNode): mOmxNode(omxNode) {
43d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
44d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
45d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    virtual status_t emptyBuffer(
46d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            int32_t bufferId, uint32_t flags,
47d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            const sp<GraphicBuffer> &buffer,
48d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            int64_t timestamp, int fenceFd) override {
49d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        CodecBuffer tBuffer;
50694ebf6734cc7af6b8cf9c032fa3e5a00a54dc84Robert Shih        native_handle_t* fenceNh = native_handle_create_from_fd(fenceFd);
51694ebf6734cc7af6b8cf9c032fa3e5a00a54dc84Robert Shih        status_t err = toStatusT(mOmxNode->emptyBuffer(
52d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih              bufferId,
53d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih              *wrapAs(&tBuffer, buffer),
54d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih              flags,
55d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih              toRawTicks(timestamp),
56694ebf6734cc7af6b8cf9c032fa3e5a00a54dc84Robert Shih              fenceNh));
57694ebf6734cc7af6b8cf9c032fa3e5a00a54dc84Robert Shih        native_handle_close(fenceNh);
58694ebf6734cc7af6b8cf9c032fa3e5a00a54dc84Robert Shih        native_handle_delete(fenceNh);
59694ebf6734cc7af6b8cf9c032fa3e5a00a54dc84Robert Shih        return err;
60d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
61d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
62d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    virtual void dispatchDataSpaceChanged(
63d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override {
64d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        Message tMsg;
65d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        tMsg.type = Message::Type::EVENT;
66d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        tMsg.fence = native_handle_create(0, 0);
67d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        tMsg.data.eventData.event = uint32_t(OMX_EventDataSpaceChanged);
68d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        tMsg.data.eventData.data1 = dataSpace;
69d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        tMsg.data.eventData.data2 = aspects;
70d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        tMsg.data.eventData.data3 = pixelFormat;
71d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        mOmxNode->dispatchMessage(tMsg);
72d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
73d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih};
74d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
75d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shihstruct TWGraphicBufferSource::TWOmxBufferSource : public IOmxBufferSource {
76d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    sp<GraphicBufferSource> mSource;
77d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
78d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    TWOmxBufferSource(const sp<GraphicBufferSource> &source): mSource(source) {
79d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
80d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
81d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    Return<void> onOmxExecuting() override {
82d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        mSource->onOmxExecuting();
83d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return Void();
84d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
85d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
86d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    Return<void> onOmxIdle() override {
87d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        mSource->onOmxIdle();
88d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return Void();
89d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
90d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
91d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    Return<void> onOmxLoaded() override {
92d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        mSource->onOmxLoaded();
93d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return Void();
94d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
95d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
96d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    Return<void> onInputBufferAdded(uint32_t bufferId) override {
97d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        mSource->onInputBufferAdded(static_cast<int32_t>(bufferId));
98d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return Void();
99d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
100d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
101d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    Return<void> onInputBufferEmptied(
102d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            uint32_t bufferId, hidl_handle const& tFence) override {
103d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        mSource->onInputBufferEmptied(
104d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih                static_cast<int32_t>(bufferId),
105d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih                native_handle_read_fd(tFence));
106d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return Void();
107d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
108d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih};
109517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
110517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa// TWGraphicBufferSource
111517b0e090680e378f056677201426ed9dc325c65Pawin VongmasaTWGraphicBufferSource::TWGraphicBufferSource(
112d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        sp<GraphicBufferSource> const& base) :
113d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    mBase(base),
114d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    mOmxBufferSource(new TWOmxBufferSource(base)) {
115517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
116517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
117d095e65c8c125c555046c60539a0f7abf0ccf271Robert ShihReturn<Status> TWGraphicBufferSource::configure(
118517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        const sp<IOmxNode>& omxNode, Dataspace dataspace) {
119d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    if (omxNode == NULL) {
120d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return toStatus(BAD_VALUE);
121d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
122d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
123d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    // Do setInputSurface() first, the node will try to enable metadata
124d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    // mode on input, and does necessary error checking. If this fails,
125d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    // we can't use this input surface on the node.
126d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    Return<Status> err(omxNode->setInputSurface(mOmxBufferSource));
127d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    status_t fnStatus = toStatusT(err);
128d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    if (fnStatus != NO_ERROR) {
129d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        ALOGE("Unable to set input surface: %d", fnStatus);
130d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return err;
131d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
132d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
133d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    // use consumer usage bits queried from encoder, but always add
134d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    // HW_VIDEO_ENCODER for backward compatibility.
135d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    uint32_t  consumerUsage;
136d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    void *_params = &consumerUsage;
137d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    uint8_t *params = static_cast<uint8_t*>(_params);
138d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    fnStatus = UNKNOWN_ERROR;
139d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    IOmxNode::getParameter_cb _hidl_cb(
140d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            [&fnStatus, &params](Status status, hidl_vec<uint8_t> const& outParams) {
141d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih                fnStatus = toStatusT(status);
142d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih                std::copy(
143d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih                        outParams.data(),
144d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih                        outParams.data() + outParams.size(),
145d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih                        params);
146d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            });
147d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    omxNode->getParameter(
148d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            static_cast<uint32_t>(OMX_IndexParamConsumerUsageBits),
149d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            inHidlBytes(&consumerUsage, sizeof(consumerUsage)),
150d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            _hidl_cb);
151d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    if (fnStatus != OK) {
152d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        consumerUsage = 0;
153d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
154d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
155d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    OMX_PARAM_PORTDEFINITIONTYPE def;
156d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    InitOMXParams(&def);
157d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    def.nPortIndex = kPortIndexInput;
158d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
159d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    _params = &def;
160d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    params = static_cast<uint8_t*>(_params);
161d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    omxNode->getParameter(
162d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            static_cast<uint32_t>(OMX_IndexParamPortDefinition),
163d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            inHidlBytes(&def, sizeof(def)),
164d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            _hidl_cb);
165d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    if (fnStatus != NO_ERROR) {
166d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        ALOGE("Failed to get port definition: %d", fnStatus);
167d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih        return toStatus(fnStatus);
168d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    }
169d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
170d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
171d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return toStatus(mBase->configure(
172d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            new TWOmxNodeWrapper(omxNode),
173d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            toRawDataspace(dataspace),
174d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            def.nBufferCountActual,
175d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            def.format.video.nFrameWidth,
176d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            def.format.video.nFrameHeight,
177d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih            consumerUsage));
178d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih}
179d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih
180d095e65c8c125c555046c60539a0f7abf0ccf271Robert ShihReturn<Status> TWGraphicBufferSource::setSuspend(
181764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        bool suspend, int64_t timeUs) {
182d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return toStatus(mBase->setSuspend(suspend, timeUs));
183517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
184517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
185d095e65c8c125c555046c60539a0f7abf0ccf271Robert ShihReturn<Status> TWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
186517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        int64_t repeatAfterUs) {
187d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return toStatus(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
188517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
189517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
190d095e65c8c125c555046c60539a0f7abf0ccf271Robert ShihReturn<Status> TWGraphicBufferSource::setMaxFps(float maxFps) {
191d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return toStatus(mBase->setMaxFps(maxFps));
192517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
193517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
194d095e65c8c125c555046c60539a0f7abf0ccf271Robert ShihReturn<Status> TWGraphicBufferSource::setTimeLapseConfig(
19522dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        double fps, double captureFps) {
19622dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    return toStatus(mBase->setTimeLapseConfig(fps, captureFps));
197517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
198517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
199d095e65c8c125c555046c60539a0f7abf0ccf271Robert ShihReturn<Status> TWGraphicBufferSource::setStartTimeUs(int64_t startTimeUs) {
200d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return toStatus(mBase->setStartTimeUs(startTimeUs));
201517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
202517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
203d095e65c8c125c555046c60539a0f7abf0ccf271Robert ShihReturn<Status> TWGraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
204d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return toStatus(mBase->setStopTimeUs(stopTimeUs));
205764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang}
206764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
20724059088a46160f731903cc66404184a531d0478Pawin VongmasaReturn<void> TWGraphicBufferSource::getStopTimeOffsetUs(
20824059088a46160f731903cc66404184a531d0478Pawin Vongmasa        getStopTimeOffsetUs_cb _hidl_cb) {
20924059088a46160f731903cc66404184a531d0478Pawin Vongmasa    // TODO: Implement this when needed.
21024059088a46160f731903cc66404184a531d0478Pawin Vongmasa    _hidl_cb(Status::OK, 0);
21124059088a46160f731903cc66404184a531d0478Pawin Vongmasa    return Void();
21224059088a46160f731903cc66404184a531d0478Pawin Vongmasa}
21324059088a46160f731903cc66404184a531d0478Pawin Vongmasa
214d095e65c8c125c555046c60539a0f7abf0ccf271Robert ShihReturn<Status> TWGraphicBufferSource::setColorAspects(
215517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa        const ColorAspects& aspects) {
216d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return toStatus(mBase->setColorAspects(toCompactColorAspects(aspects)));
217517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
218517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
219d095e65c8c125c555046c60539a0f7abf0ccf271Robert ShihReturn<Status> TWGraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
220d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return toStatus(mBase->setTimeOffsetUs(timeOffsetUs));
221517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
222517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
223d095e65c8c125c555046c60539a0f7abf0ccf271Robert ShihReturn<Status> TWGraphicBufferSource::signalEndOfInputStream() {
224d095e65c8c125c555046c60539a0f7abf0ccf271Robert Shih    return toStatus(mBase->signalEndOfInputStream());
225517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}
226517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa
227517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}  // namespace implementation
228517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}  // namespace V1_0
229517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}  // namespace omx
230517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}  // namespace media
231517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}  // namespace hardware
232517b0e090680e378f056677201426ed9dc325c65Pawin Vongmasa}  // namespace android
233