content/media/omx/OMXCodecProxy.cpp

Fri, 16 Jan 2015 04:50:19 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 04:50:19 +0100
branch
TOR_BUG_9701
changeset 13
44a2da4a2ab2
permissions
-rw-r--r--

Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     5  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 //#define LOG_NDEBUG 0
     8 #define LOG_TAG "OMXCodecProxy"
    10 #include <binder/IPCThreadState.h>
    11 #include <cutils/properties.h>
    12 #include <stagefright/foundation/ADebug.h>
    13 #include <stagefright/MetaData.h>
    14 #include <stagefright/OMXCodec.h>
    15 #include <utils/Log.h>
    17 #include "nsDebug.h"
    19 #include "IMediaResourceManagerService.h"
    21 #include "OMXCodecProxy.h"
    23 namespace android {
    25 // static
    26 sp<OMXCodecProxy> OMXCodecProxy::Create(
    27         const sp<IOMX> &omx,
    28         const sp<MetaData> &meta, bool createEncoder,
    29         const sp<MediaSource> &source,
    30         const char *matchComponentName,
    31         uint32_t flags,
    32         const sp<ANativeWindow> &nativeWindow)
    33 {
    34   sp<OMXCodecProxy> proxy;
    36   const char *mime;
    37   if (!meta->findCString(kKeyMIMEType, &mime)) {
    38     return nullptr;
    39   }
    41   if (!strncasecmp(mime, "video/", 6)) {
    42     proxy = new OMXCodecProxy(omx, meta, createEncoder, source, matchComponentName, flags, nativeWindow);
    43   }
    44   return proxy;
    45 }
    48 OMXCodecProxy::OMXCodecProxy(
    49         const sp<IOMX> &omx,
    50         const sp<MetaData> &meta,
    51         bool createEncoder,
    52         const sp<MediaSource> &source,
    53         const char *matchComponentName,
    54         uint32_t flags,
    55         const sp<ANativeWindow> &nativeWindow)
    56     : mOMX(omx),
    57       mSrcMeta(meta),
    58       mIsEncoder(createEncoder),
    59       mSource(source),
    60       mComponentName(nullptr),
    61       mFlags(flags),
    62       mNativeWindow(nativeWindow),
    63       mState(MediaResourceManagerClient::CLIENT_STATE_WAIT_FOR_RESOURCE)
    64 {
    65 }
    67 OMXCodecProxy::~OMXCodecProxy()
    68 {
    69   mState = MediaResourceManagerClient::CLIENT_STATE_SHUTDOWN;
    71   if (mOMXCodec.get()) {
    72     wp<MediaSource> tmp = mOMXCodec;
    73     mOMXCodec.clear();
    74     while (tmp.promote() != nullptr) {
    75         // this value come from stagefrigh's AwesomePlayer.
    76         usleep(1000);
    77     }
    78   }
    79   // Complete all pending Binder ipc transactions
    80   IPCThreadState::self()->flushCommands();
    82   if (mManagerService.get() && mClient.get()) {
    83     mManagerService->cancelClient(mClient);
    84   }
    86   mSource.clear();
    87   free(mComponentName);
    88   mComponentName = nullptr;
    89 }
    91 MediaResourceManagerClient::State OMXCodecProxy::getState()
    92 {
    93   Mutex::Autolock autoLock(mLock);
    94   return mState;
    95 }
    97 void OMXCodecProxy::setEventListener(const wp<OMXCodecProxy::EventListener>& listener)
    98 {
    99   Mutex::Autolock autoLock(mLock);
   100   mEventListener = listener;
   101 }
   103 void OMXCodecProxy::notifyStatusChangedLocked()
   104 {
   105   if (mEventListener != nullptr) {
   106     sp<EventListener> listener = mEventListener.promote();
   107     if (listener != nullptr) {
   108       listener->statusChanged();
   109     }
   110   }
   111 }
   113 void OMXCodecProxy::requestResource()
   114 {
   115   Mutex::Autolock autoLock(mLock);
   117   if (mClient.get()) {
   118     return;
   119   }
   120   sp<MediaResourceManagerClient::EventListener> listener = this;
   121   mClient = new MediaResourceManagerClient(listener);
   123   mManagerService = mClient->getMediaResourceManagerService();
   124   if (!mManagerService.get()) {
   125     mClient = nullptr;
   126     return;
   127   }
   129   mManagerService->requestMediaResource(mClient, MediaResourceManagerClient::HW_VIDEO_DECODER);
   130 }
   132 bool OMXCodecProxy::IsWaitingResources()
   133 {
   134   Mutex::Autolock autoLock(mLock);
   135   return mState == MediaResourceManagerClient::CLIENT_STATE_WAIT_FOR_RESOURCE;
   136 }
   138 // called on Binder ipc thread
   139 void OMXCodecProxy::statusChanged(int event)
   140 {
   141   Mutex::Autolock autoLock(mLock);
   143   if (mState != MediaResourceManagerClient::CLIENT_STATE_WAIT_FOR_RESOURCE) {
   144     return;
   145   }
   147   mState = (MediaResourceManagerClient::State) event;
   148   if (mState != MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) {
   149     return;
   150   }
   152   const char *mime;
   153   if (!mSrcMeta->findCString(kKeyMIMEType, &mime)) {
   154     mState = MediaResourceManagerClient::CLIENT_STATE_SHUTDOWN;
   155     notifyStatusChangedLocked();
   156     return;
   157   }
   159   if (!strncasecmp(mime, "video/", 6)) {
   160     sp<MediaSource> codec;
   161     mOMXCodec = OMXCodec::Create(mOMX, mSrcMeta, mIsEncoder, mSource, mComponentName, mFlags, mNativeWindow);
   162     if (mOMXCodec == nullptr) {
   163       mState = MediaResourceManagerClient::CLIENT_STATE_SHUTDOWN;
   164       notifyStatusChangedLocked();
   165       return;
   166     }
   167     // Check if this video is sized such that we're comfortable
   168     // possibly using an OMX decoder.
   169     int32_t maxWidth, maxHeight;
   170     char propValue[PROPERTY_VALUE_MAX];
   171     property_get("ro.moz.omx.hw.max_width", propValue, "-1");
   172     maxWidth = atoi(propValue);
   173     property_get("ro.moz.omx.hw.max_height", propValue, "-1");
   174     maxHeight = atoi(propValue);
   176     int32_t width = -1, height = -1;
   177     if (maxWidth > 0 && maxHeight > 0 &&
   178         !(mOMXCodec->getFormat()->findInt32(kKeyWidth, &width) &&
   179           mOMXCodec->getFormat()->findInt32(kKeyHeight, &height) &&
   180           width * height <= maxWidth * maxHeight)) {
   181       printf_stderr("Failed to get video size, or it was too large for HW decoder (<w=%d, h=%d> but <maxW=%d, maxH=%d>)",
   182                     width, height, maxWidth, maxHeight);
   183       mOMXCodec.clear();
   184       mState = MediaResourceManagerClient::CLIENT_STATE_SHUTDOWN;
   185       notifyStatusChangedLocked();
   186       return;
   187     }
   189     if (mOMXCodec->start() != OK) {
   190       NS_WARNING("Couldn't start OMX video source");
   191       mOMXCodec.clear();
   192       mState = MediaResourceManagerClient::CLIENT_STATE_SHUTDOWN;
   193       notifyStatusChangedLocked();
   194       return;
   195     }
   196   }
   197   notifyStatusChangedLocked();
   198 }
   200 status_t OMXCodecProxy::start(MetaData *params)
   201 {
   202   Mutex::Autolock autoLock(mLock);
   204   if (mState != MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) {
   205     return NO_INIT;
   206   }
   207   CHECK(mOMXCodec.get() != nullptr);
   208   return mOMXCodec->start();
   209 }
   211 status_t OMXCodecProxy::stop()
   212 {
   213   Mutex::Autolock autoLock(mLock);
   215   if (mState != MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) {
   216     return NO_INIT;
   217   }
   218   CHECK(mOMXCodec.get() != nullptr);
   219   return mOMXCodec->stop();
   220 }
   222 sp<MetaData> OMXCodecProxy::getFormat()
   223 {
   224   Mutex::Autolock autoLock(mLock);
   226   if (mState != MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) {
   227     sp<MetaData> meta = new MetaData;
   228     return meta;
   229   }
   230   CHECK(mOMXCodec.get() != nullptr);
   231   return mOMXCodec->getFormat();
   232 }
   234 status_t OMXCodecProxy::read(MediaBuffer **buffer, const ReadOptions *options)
   235 {
   236   Mutex::Autolock autoLock(mLock);
   238   if (mState != MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) {
   239     return NO_INIT;
   240   }
   241   CHECK(mOMXCodec.get() != nullptr);
   242   return mOMXCodec->read(buffer, options);
   243 }
   245 status_t OMXCodecProxy::pause()
   246 {
   247   Mutex::Autolock autoLock(mLock);
   249   if (mState != MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) {
   250     return NO_INIT;
   251   }
   252   CHECK(mOMXCodec.get() != nullptr);
   253   return mOMXCodec->pause();
   254 }
   256 }  // namespace android

mercurial