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