Home | History | Annotate | Download | only in 1.0
      1 /*
      2  * Copyright 2016, 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 "TWGraphicBufferSource"
     19 
     20 #include <media/stagefright/omx/1.0/WGraphicBufferSource.h>
     21 #include <media/stagefright/omx/1.0/WOmxNode.h>
     22 #include <media/stagefright/omx/1.0/Conversion.h>
     23 #include <media/stagefright/omx/OMXUtils.h>
     24 #include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
     25 #include <android/hardware/media/omx/1.0/IOmxNode.h>
     26 #include <media/openmax/OMX_Component.h>
     27 #include <media/openmax/OMX_IndexExt.h>
     28 
     29 namespace android {
     30 namespace hardware {
     31 namespace media {
     32 namespace omx {
     33 namespace V1_0 {
     34 namespace implementation {
     35 
     36 static const OMX_U32 kPortIndexInput = 0;
     37 
     38 struct TWGraphicBufferSource::TWOmxNodeWrapper : public IOmxNodeWrapper {
     39     sp<IOmxNode> mOmxNode;
     40 
     41     TWOmxNodeWrapper(const sp<IOmxNode> &omxNode): mOmxNode(omxNode) {
     42     }
     43 
     44     virtual status_t emptyBuffer(
     45             int32_t bufferId, uint32_t flags,
     46             const sp<GraphicBuffer> &buffer,
     47             int64_t timestamp, int fenceFd) override {
     48         CodecBuffer tBuffer;
     49         native_handle_t* fenceNh = native_handle_create_from_fd(fenceFd);
     50         status_t err = toStatusT(mOmxNode->emptyBuffer(
     51               bufferId,
     52               *wrapAs(&tBuffer, buffer),
     53               flags,
     54               toRawTicks(timestamp),
     55               fenceNh));
     56         native_handle_close(fenceNh);
     57         native_handle_delete(fenceNh);
     58         return err;
     59     }
     60 
     61     virtual void dispatchDataSpaceChanged(
     62             int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override {
     63         Message tMsg;
     64         tMsg.type = Message::Type::EVENT;
     65         tMsg.fence = native_handle_create(0, 0);
     66         tMsg.data.eventData.event = uint32_t(OMX_EventDataSpaceChanged);
     67         tMsg.data.eventData.data1 = dataSpace;
     68         tMsg.data.eventData.data2 = aspects;
     69         tMsg.data.eventData.data3 = pixelFormat;
     70         if (!mOmxNode->dispatchMessage(tMsg).isOk()) {
     71             ALOGE("TWOmxNodeWrapper failed to dispatch message "
     72                     "OMX_EventDataSpaceChanged: "
     73                     "dataSpace = %ld, aspects = %ld, pixelFormat = %ld",
     74                     static_cast<long>(dataSpace),
     75                     static_cast<long>(aspects),
     76                     static_cast<long>(pixelFormat));
     77         }
     78     }
     79 };
     80 
     81 struct TWGraphicBufferSource::TWOmxBufferSource : public IOmxBufferSource {
     82     sp<GraphicBufferSource> mSource;
     83 
     84     TWOmxBufferSource(const sp<GraphicBufferSource> &source): mSource(source) {
     85     }
     86 
     87     Return<void> onOmxExecuting() override {
     88         mSource->onOmxExecuting();
     89         return Void();
     90     }
     91 
     92     Return<void> onOmxIdle() override {
     93         mSource->onOmxIdle();
     94         return Void();
     95     }
     96 
     97     Return<void> onOmxLoaded() override {
     98         mSource->onOmxLoaded();
     99         return Void();
    100     }
    101 
    102     Return<void> onInputBufferAdded(uint32_t bufferId) override {
    103         mSource->onInputBufferAdded(static_cast<int32_t>(bufferId));
    104         return Void();
    105     }
    106 
    107     Return<void> onInputBufferEmptied(
    108             uint32_t bufferId, hidl_handle const& tFence) override {
    109         mSource->onInputBufferEmptied(
    110                 static_cast<int32_t>(bufferId),
    111                 native_handle_read_fd(tFence));
    112         return Void();
    113     }
    114 };
    115 
    116 // TWGraphicBufferSource
    117 TWGraphicBufferSource::TWGraphicBufferSource(
    118         sp<GraphicBufferSource> const& base) :
    119     mBase(base),
    120     mOmxBufferSource(new TWOmxBufferSource(base)) {
    121 }
    122 
    123 Return<Status> TWGraphicBufferSource::configure(
    124         const sp<IOmxNode>& omxNode, Dataspace dataspace) {
    125     if (omxNode == NULL) {
    126         return toStatus(BAD_VALUE);
    127     }
    128 
    129     // Do setInputSurface() first, the node will try to enable metadata
    130     // mode on input, and does necessary error checking. If this fails,
    131     // we can't use this input surface on the node.
    132     Return<Status> err(omxNode->setInputSurface(mOmxBufferSource));
    133     status_t fnStatus = toStatusT(err);
    134     if (fnStatus != NO_ERROR) {
    135         ALOGE("Unable to set input surface: %d", fnStatus);
    136         return err;
    137     }
    138 
    139     // use consumer usage bits queried from encoder, but always add
    140     // HW_VIDEO_ENCODER for backward compatibility.
    141     uint32_t  consumerUsage;
    142     void *_params = &consumerUsage;
    143     uint8_t *params = static_cast<uint8_t*>(_params);
    144     fnStatus = UNKNOWN_ERROR;
    145     IOmxNode::getParameter_cb _hidl_cb(
    146             [&fnStatus, &params](Status status, hidl_vec<uint8_t> const& outParams) {
    147                 fnStatus = toStatusT(status);
    148                 std::copy(
    149                         outParams.data(),
    150                         outParams.data() + outParams.size(),
    151                         params);
    152             });
    153     auto transStatus = omxNode->getParameter(
    154             static_cast<uint32_t>(OMX_IndexParamConsumerUsageBits),
    155             inHidlBytes(&consumerUsage, sizeof(consumerUsage)),
    156             _hidl_cb);
    157     if (!transStatus.isOk()) {
    158         return toStatus(FAILED_TRANSACTION);
    159     }
    160     if (fnStatus != OK) {
    161         consumerUsage = 0;
    162     }
    163 
    164     OMX_PARAM_PORTDEFINITIONTYPE def;
    165     InitOMXParams(&def);
    166     def.nPortIndex = kPortIndexInput;
    167 
    168     _params = &def;
    169     params = static_cast<uint8_t*>(_params);
    170     transStatus = omxNode->getParameter(
    171             static_cast<uint32_t>(OMX_IndexParamPortDefinition),
    172             inHidlBytes(&def, sizeof(def)),
    173             _hidl_cb);
    174     if (!transStatus.isOk()) {
    175         return toStatus(FAILED_TRANSACTION);
    176     }
    177     if (fnStatus != NO_ERROR) {
    178         ALOGE("Failed to get port definition: %d", fnStatus);
    179         return toStatus(fnStatus);
    180     }
    181 
    182 
    183     return toStatus(mBase->configure(
    184             new TWOmxNodeWrapper(omxNode),
    185             toRawDataspace(dataspace),
    186             def.nBufferCountActual,
    187             def.format.video.nFrameWidth,
    188             def.format.video.nFrameHeight,
    189             consumerUsage));
    190 }
    191 
    192 Return<Status> TWGraphicBufferSource::setSuspend(
    193         bool suspend, int64_t timeUs) {
    194     return toStatus(mBase->setSuspend(suspend, timeUs));
    195 }
    196 
    197 Return<Status> TWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
    198         int64_t repeatAfterUs) {
    199     return toStatus(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
    200 }
    201 
    202 Return<Status> TWGraphicBufferSource::setMaxFps(float maxFps) {
    203     return toStatus(mBase->setMaxFps(maxFps));
    204 }
    205 
    206 Return<Status> TWGraphicBufferSource::setTimeLapseConfig(
    207         double fps, double captureFps) {
    208     return toStatus(mBase->setTimeLapseConfig(fps, captureFps));
    209 }
    210 
    211 Return<Status> TWGraphicBufferSource::setStartTimeUs(int64_t startTimeUs) {
    212     return toStatus(mBase->setStartTimeUs(startTimeUs));
    213 }
    214 
    215 Return<Status> TWGraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
    216     return toStatus(mBase->setStopTimeUs(stopTimeUs));
    217 }
    218 
    219 Return<void> TWGraphicBufferSource::getStopTimeOffsetUs(
    220         getStopTimeOffsetUs_cb _hidl_cb) {
    221     status_t status;
    222     int64_t stopTimeOffsetUs;
    223     status = mBase->getStopTimeOffsetUs(&stopTimeOffsetUs);
    224     _hidl_cb(toStatus(status), stopTimeOffsetUs);
    225     return Void();
    226 }
    227 
    228 Return<Status> TWGraphicBufferSource::setColorAspects(
    229         const ColorAspects& aspects) {
    230     return toStatus(mBase->setColorAspects(toCompactColorAspects(aspects)));
    231 }
    232 
    233 Return<Status> TWGraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
    234     return toStatus(mBase->setTimeOffsetUs(timeOffsetUs));
    235 }
    236 
    237 Return<Status> TWGraphicBufferSource::signalEndOfInputStream() {
    238     return toStatus(mBase->signalEndOfInputStream());
    239 }
    240 
    241 }  // namespace implementation
    242 }  // namespace V1_0
    243 }  // namespace omx
    244 }  // namespace media
    245 }  // namespace hardware
    246 }  // namespace android
    247