diff options
| -rw-r--r-- | include/media/stagefright/MediaCodecSource.h | 3 | ||||
| -rw-r--r-- | include/media/stagefright/MetaData.h | 4 | ||||
| -rw-r--r-- | media/libstagefright/ACodec.cpp | 16 | ||||
| -rw-r--r-- | media/libstagefright/CameraSource.cpp | 10 | ||||
| -rw-r--r-- | media/libstagefright/MediaCodecList.cpp | 3 | ||||
| -rw-r--r-- | media/libstagefright/MediaCodecSource.cpp | 29 | ||||
| -rw-r--r-- | media/libstagefright/codecs/mp3dec/SoftMP3.cpp | 8 | ||||
| -rw-r--r-- | media/libstagefright/omx/GraphicBufferSource.cpp | 9 | ||||
| -rw-r--r-- | media/libstagefright/omx/GraphicBufferSource.h | 1 | ||||
| -rw-r--r-- | media/libstagefright/omx/OMXNodeInstance.cpp | 34 | ||||
| -rw-r--r-- | media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp | 11 | ||||
| -rw-r--r-- | services/camera/libcameraservice/device3/Camera3Device.cpp | 29 | ||||
| -rw-r--r-- | services/camera/libcameraservice/device3/Camera3Device.h | 3 | 
13 files changed, 129 insertions, 31 deletions
diff --git a/include/media/stagefright/MediaCodecSource.h b/include/media/stagefright/MediaCodecSource.h index a991b02..71f58a9 100644 --- a/include/media/stagefright/MediaCodecSource.h +++ b/include/media/stagefright/MediaCodecSource.h @@ -108,6 +108,9 @@ private:      bool mStarted;      bool mStopping;      bool mDoMoreWorkPending; +    bool mSetEncoderFormat; +    int mEncoderFormat; +    int mEncoderDataSpace;      sp<AMessage> mEncoderActivityNotify;      sp<IGraphicBufferProducer> mGraphicBufferProducer;      sp<IGraphicBufferConsumer> mGraphicBufferConsumer; diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h index ca80123..726b197 100644 --- a/include/media/stagefright/MetaData.h +++ b/include/media/stagefright/MetaData.h @@ -70,7 +70,9 @@ enum {      kKeyDriftTime         = 'dftT',  // int64_t (usecs)      kKeyAnchorTime        = 'ancT',  // int64_t (usecs)      kKeyDuration          = 'dura',  // int64_t (usecs) -    kKeyColorFormat       = 'colf', +    kKeyPixelFormat       = 'pixf',  // int32_t +    kKeyColorFormat       = 'colf',  // int32_t +    kKeyColorSpace        = 'cols',  // int32_t      kKeyPlatformPrivate   = 'priv',  // pointer      kKeyDecoderComponent  = 'decC',  // cstring      kKeyBufferID          = 'bfID', diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index bb53ce6..c6e45af 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -1639,6 +1639,14 @@ status_t ACodec::configureCodec(          if (mInputMetadataType == kMetadataBufferTypeGrallocSource) {              mInputMetadataType = kMetadataBufferTypeCameraSource;          } + +        uint32_t usageBits; +        if (mOMX->getParameter( +                mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, +                &usageBits, sizeof(usageBits)) == OK) { +            inputFormat->setInt32( +                    "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN)); +        }      }      int32_t prependSPSPPS = 0; @@ -5748,6 +5756,14 @@ status_t ACodec::LoadedState::setupInputSurface() {          }      } +    uint32_t usageBits; +    if (mCodec->mOMX->getParameter( +            mCodec->mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, +            &usageBits, sizeof(usageBits)) == OK) { +        mCodec->mInputFormat->setInt32( +                "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN)); +    } +      return OK;  } diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp index 2606e44..bc34bcf 100644 --- a/media/libstagefright/CameraSource.cpp +++ b/media/libstagefright/CameraSource.cpp @@ -670,9 +670,13 @@ status_t CameraSource::start(MetaData *meta) {              mNumInputBuffers = nBuffers;          } -        // TODO: Read in format/dataspace from somewhere -        // Uncomment to test SW encoders until TODO is resolved -        // mEncoderFormat = HAL_PIXEL_FORMAT_YCbCr_420_888; +        // apply encoder color format if specified +        if (meta->findInt32(kKeyPixelFormat, &mEncoderFormat)) { +            ALOGV("Using encoder format: %#x", mEncoderFormat); +        } +        if (meta->findInt32(kKeyColorSpace, &mEncoderDataSpace)) { +            ALOGV("Using encoder data space: %#x", mEncoderDataSpace); +        }      }      status_t err; diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp index ab49c11..7ea5cbd 100644 --- a/media/libstagefright/MediaCodecList.cpp +++ b/media/libstagefright/MediaCodecList.cpp @@ -175,6 +175,7 @@ MediaCodecList::MediaCodecList()        mUpdate(false),        mGlobalSettings(new AMessage()) {      parseTopLevelXMLFile("/etc/media_codecs.xml"); +    parseTopLevelXMLFile("/etc/media_codecs_performance.xml", true/* ignore_errors */);      parseTopLevelXMLFile(kProfilingResults, true/* ignore_errors */);  } @@ -935,7 +936,7 @@ status_t MediaCodecList::addLimit(const char **attrs) {      if (name == "aspect-ratio" || name == "bitrate" || name == "block-count"              || name == "blocks-per-second" || name == "complexity"              || name == "frame-rate" || name == "quality" || name == "size" -            || name == "measured-blocks-per-second" || name == "measured-frame-rate") { +            || name == "measured-blocks-per-second" || name.startsWith("measured-frame-rate-")) {          AString min, max;          if (msg->findString("min", &min) && msg->findString("max", &max)) {              min.append("-"); diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp index e089c46..7f9f824 100644 --- a/media/libstagefright/MediaCodecSource.cpp +++ b/media/libstagefright/MediaCodecSource.cpp @@ -39,6 +39,9 @@  namespace android { +const int kDefaultSwVideoEncoderFormat = HAL_PIXEL_FORMAT_YCbCr_420_888; +const int kDefaultSwVideoEncoderDataSpace = HAL_DATASPACE_BT709; +  struct MediaCodecSource::Puller : public AHandler {      Puller(const sp<MediaSource> &source); @@ -341,6 +344,9 @@ MediaCodecSource::MediaCodecSource(        mStarted(false),        mStopping(false),        mDoMoreWorkPending(false), +      mSetEncoderFormat(false), +      mEncoderFormat(0), +      mEncoderDataSpace(0),        mGraphicBufferConsumer(consumer),        mFirstSampleTimeUs(-1ll),        mEncoderReachedEOS(false), @@ -438,6 +444,18 @@ status_t MediaCodecSource::initEncoder() {          }      } +    sp<AMessage> inputFormat; +    int32_t usingSwReadOften; +    mSetEncoderFormat = false; +    if (mEncoder->getInputFormat(&inputFormat) == OK +            && inputFormat->findInt32("using-sw-read-often", &usingSwReadOften) +            && usingSwReadOften) { +        // this is a SW encoder; signal source to allocate SW readable buffers +        mSetEncoderFormat = true; +        mEncoderFormat = kDefaultSwVideoEncoderFormat; +        mEncoderDataSpace = kDefaultSwVideoEncoderDataSpace; +    } +      err = mEncoder->start();      if (err != OK) { @@ -632,8 +650,17 @@ status_t MediaCodecSource::onStart(MetaData *params) {          resume(startTimeUs);      } else {          CHECK(mPuller != NULL); +        sp<MetaData> meta = params; +        if (mSetEncoderFormat) { +            if (meta == NULL) { +                meta = new MetaData; +            } +            meta->setInt32(kKeyPixelFormat, mEncoderFormat); +            meta->setInt32(kKeyColorSpace, mEncoderDataSpace); +        } +          sp<AMessage> notify = new AMessage(kWhatPullerNotify, mReflector); -        err = mPuller->start(params, notify); +        err = mPuller->start(meta.get(), notify);          if (err != OK) {              return err;          } diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp index 5396022..f743b1c 100644 --- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp +++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp @@ -283,6 +283,11 @@ void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) {              } else {                  // This is recoverable, just ignore the current frame and                  // play silence instead. + +                // TODO: should we skip silence (and consume input data) +                // if mIsFirst is true as we may not have a valid +                // mConfig->samplingRate and mConfig->num_channels? +                ALOGV_IF(mIsFirst, "insufficient data for first frame, sending silence");                  memset(outHeader->pBuffer,                         0,                         mConfig->outputFrameSize * sizeof(int16_t)); @@ -317,8 +322,7 @@ void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) {          }          outHeader->nTimeStamp = -            mAnchorTimeUs -                + (mNumFramesOutput * 1000000ll) / mConfig->samplingRate; +            mAnchorTimeUs + (mNumFramesOutput * 1000000ll) / mSamplingRate;          if (inHeader) {              CHECK_GE(inHeader->nFilledLen, mConfig->inputBufferUsedLength); diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp index 31c6975..a424819 100644 --- a/media/libstagefright/omx/GraphicBufferSource.cpp +++ b/media/libstagefright/omx/GraphicBufferSource.cpp @@ -23,6 +23,7 @@  #include "GraphicBufferSource.h"  #include <OMX_Core.h> +#include <OMX_IndexExt.h>  #include <media/stagefright/foundation/ADebug.h>  #include <media/stagefright/foundation/AMessage.h> @@ -110,6 +111,7 @@ GraphicBufferSource::GraphicBufferSource(          uint32_t bufferWidth,          uint32_t bufferHeight,          uint32_t bufferCount, +        uint32_t consumerUsage,          const sp<IGraphicBufferConsumer> &consumer) :      mInitCheck(UNKNOWN_ERROR),      mNodeInstance(nodeInstance), @@ -152,7 +154,12 @@ GraphicBufferSource::GraphicBufferSource(          BufferQueue::createBufferQueue(&mProducer, &mConsumer);          mConsumer->setConsumerName(name); -        mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER); + +        // use consumer usage bits queried from encoder, but always add HW_VIDEO_ENCODER +        // for backward compatibility. +        consumerUsage |= GRALLOC_USAGE_HW_VIDEO_ENCODER; +        mConsumer->setConsumerUsageBits(consumerUsage); +          mInitCheck = mConsumer->setMaxAcquiredBufferCount(bufferCount);          if (mInitCheck != NO_ERROR) {              ALOGE("Unable to set BQ max acquired buffer count to %u: %d", diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h index 3f64088..2f929d9 100644 --- a/media/libstagefright/omx/GraphicBufferSource.h +++ b/media/libstagefright/omx/GraphicBufferSource.h @@ -55,6 +55,7 @@ public:              uint32_t bufferWidth,              uint32_t bufferHeight,              uint32_t bufferCount, +            uint32_t consumerUsage,              const sp<IGraphicBufferConsumer> &consumer = NULL      ); diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index 147aae7..9f1c5d8 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -834,7 +834,8 @@ status_t OMXNodeInstance::updateGraphicBufferInMeta_l(      }      CLOG_BUFFER(updateGraphicBufferInMeta, "%s:%u, %#x := %p", -            portString(portIndex), portIndex, buffer, graphicBuffer->handle); +            portString(portIndex), portIndex, buffer, +            graphicBuffer == NULL ? NULL : graphicBuffer->handle);      return OK;  } @@ -885,10 +886,18 @@ status_t OMXNodeInstance::createGraphicBufferSource(          return INVALID_OPERATION;      } +    uint32_t usageBits; +    oerr = OMX_GetParameter( +            mHandle, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, &usageBits); +    if (oerr != OMX_ErrorNone) { +        usageBits = 0; +    } +      sp<GraphicBufferSource> bufferSource = new GraphicBufferSource(this,              def.format.video.nFrameWidth,              def.format.video.nFrameHeight,              def.nBufferCountActual, +            usageBits,              bufferConsumer);      if ((err = bufferSource->initCheck()) != OK) { @@ -1607,7 +1616,12 @@ OMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(OMX::buffer_id buffer) {          return NULL;      }      Mutex::Autolock autoLock(mBufferIDLock); -    return mBufferIDToBufferHeader.valueFor(buffer); +    ssize_t index = mBufferIDToBufferHeader.indexOfKey(buffer); +    if (index < 0) { +        CLOGW("findBufferHeader: buffer %u not found", buffer); +        return NULL; +    } +    return mBufferIDToBufferHeader.valueAt(index);  }  OMX::buffer_id OMXNodeInstance::findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) { @@ -1615,7 +1629,12 @@ OMX::buffer_id OMXNodeInstance::findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader)          return 0;      }      Mutex::Autolock autoLock(mBufferIDLock); -    return mBufferHeaderToBufferID.valueFor(bufferHeader); +    ssize_t index = mBufferHeaderToBufferID.indexOfKey(bufferHeader); +    if (index < 0) { +        CLOGW("findBufferID: bufferHeader %p not found", bufferHeader); +        return 0; +    } +    return mBufferHeaderToBufferID.valueAt(index);  }  void OMXNodeInstance::invalidateBufferID(OMX::buffer_id buffer) { @@ -1623,8 +1642,13 @@ void OMXNodeInstance::invalidateBufferID(OMX::buffer_id buffer) {          return;      }      Mutex::Autolock autoLock(mBufferIDLock); -    mBufferHeaderToBufferID.removeItem(mBufferIDToBufferHeader.valueFor(buffer)); -    mBufferIDToBufferHeader.removeItem(buffer); +    ssize_t index = mBufferIDToBufferHeader.indexOfKey(buffer); +    if (index < 0) { +        CLOGW("invalidateBufferID: buffer %u not found", buffer); +        return; +    } +    mBufferHeaderToBufferID.removeItem(mBufferIDToBufferHeader.valueAt(index)); +    mBufferIDToBufferHeader.removeItemsAt(index);  }  }  // namespace android diff --git a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp index 9dd26fb..8ea7a6e 100644 --- a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp +++ b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp @@ -34,6 +34,8 @@  #include <ui/GraphicBuffer.h>  #include <ui/GraphicBufferMapper.h> +#include <OMX_IndexExt.h> +  namespace android {  const static OMX_COLOR_FORMATTYPE kSupportedColorFormats[] = { @@ -293,7 +295,7 @@ OMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalSetParameter(  OMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalGetParameter(          OMX_INDEXTYPE index, OMX_PTR param) { -    switch (index) { +    switch ((int)index) {          case OMX_IndexParamVideoErrorCorrection:          {              return OMX_ErrorNotImplemented; @@ -343,6 +345,13 @@ OMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalGetParameter(              return OMX_ErrorNone;          } +        case OMX_IndexParamConsumerUsageBits: +        { +            OMX_U32 *usageBits = (OMX_U32 *)param; +            *usageBits = GRALLOC_USAGE_SW_READ_OFTEN; +            return OMX_ErrorNone; +        } +          default:              return SimpleSoftOMXComponent::internalGetParameter(index, param);      } diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 4b55dad..9e73b5c 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -164,9 +164,17 @@ status_t Camera3Device::initialize(CameraModule *module)          return res;      } -    /** Start up request queue thread */ +    bool aeLockAvailable = false; +    camera_metadata_ro_entry aeLockAvailableEntry; +    res = find_camera_metadata_ro_entry(info.static_camera_characteristics, +            ANDROID_CONTROL_AE_LOCK_AVAILABLE, &aeLockAvailableEntry); +    if (res == OK && aeLockAvailableEntry.count > 0) { +        aeLockAvailable = (aeLockAvailableEntry.data.u8[0] == +                ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE); +    } -    mRequestThread = new RequestThread(this, mStatusTracker, device); +    /** Start up request queue thread */ +    mRequestThread = new RequestThread(this, mStatusTracker, device, aeLockAvailable);      res = mRequestThread->run(String8::format("C3Dev-%d-ReqQueue", mId).string());      if (res != OK) {          SET_ERR_L("Unable to start request queue thread: %s (%d)", @@ -2472,7 +2480,8 @@ CameraMetadata Camera3Device::getLatestRequestLocked() {  Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,          sp<StatusTracker> statusTracker, -        camera3_device_t *hal3Device) : +        camera3_device_t *hal3Device, +        bool aeLockAvailable) :          Thread(/*canCallJava*/false),          mParent(parent),          mStatusTracker(statusTracker), @@ -2485,19 +2494,9 @@ Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,          mLatestRequestId(NAME_NOT_FOUND),          mCurrentAfTriggerId(0),          mCurrentPreCaptureTriggerId(0), -        mRepeatingLastFrameNumber(NO_IN_FLIGHT_REPEATING_FRAMES) { +        mRepeatingLastFrameNumber(NO_IN_FLIGHT_REPEATING_FRAMES), +        mAeLockAvailable(aeLockAvailable) {      mStatusId = statusTracker->addComponent(); - -    mAeLockAvailable = false; -    sp<Camera3Device> p = parent.promote(); -    if (p != NULL) { -        camera_metadata_ro_entry aeLockAvailable = -                p->info().find(ANDROID_CONTROL_AE_LOCK_AVAILABLE); -        if (aeLockAvailable.count > 0) { -            mAeLockAvailable = (aeLockAvailable.data.u8[0] == -                    ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE); -        } -    }  }  void Camera3Device::RequestThread::setNotificationListener( diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index bb4bcc4..31b6132 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -389,7 +389,8 @@ class Camera3Device :          RequestThread(wp<Camera3Device> parent,                  sp<camera3::StatusTracker> statusTracker, -                camera3_device_t *hal3Device); +                camera3_device_t *hal3Device, +                bool aeLockAvailable);          void     setNotificationListener(NotificationListener *listener);  | 
