Home | History | Annotate | Download | only in omx
      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