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, ¶ms](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