Merge "Allow mediaextractor/mediacodec to connect to tombstoned."
diff --git a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
index 3512730..0771fc8 100644
--- a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
+++ b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
@@ -54,6 +54,22 @@
void beginConfigure();
/**
+ * The standard operating mode for a camera device; all API guarantees are in force
+ */
+ const int NORMAL_MODE = 0;
+
+ /**
+ * High-speed recording mode; only two outputs targeting preview and video recording may be
+ * used, and requests must be batched.
+ */
+ const int CONSTRAINED_HIGH_SPEED_MODE = 1;
+
+ /**
+ * Start of custom vendor modes
+ */
+ const int VENDOR_MODE_START = 0x8000;
+
+ /**
* End the device configuration.
*
* <p>
@@ -61,8 +77,10 @@
* a call to beginConfigure and subsequent createStream/deleteStream calls). This
* must be called before any requests can be submitted.
* <p>
+ * @param operatingMode The kind of session to create; either NORMAL_MODE or
+ * CONSTRAINED_HIGH_SPEED_MODE. Must be a non-negative value.
*/
- void endConfigure(boolean isConstrainedHighSpeed);
+ void endConfigure(int operatingMode);
void deleteStream(int streamId);
diff --git a/cmds/screenrecord/EglWindow.cpp b/cmds/screenrecord/EglWindow.cpp
index c16f2ad..5ea0706 100644
--- a/cmds/screenrecord/EglWindow.cpp
+++ b/cmds/screenrecord/EglWindow.cpp
@@ -21,7 +21,6 @@
#define EGL_EGLEXT_PROTOTYPES
#include <gui/BufferQueue.h>
-#include <gui/GraphicBufferAlloc.h>
#include <gui/Surface.h>
#include "EglWindow.h"
diff --git a/cmds/screenrecord/Overlay.cpp b/cmds/screenrecord/Overlay.cpp
index be993e0..aa800d8 100644
--- a/cmds/screenrecord/Overlay.cpp
+++ b/cmds/screenrecord/Overlay.cpp
@@ -23,7 +23,6 @@
#include <utils/Log.h>
#include <gui/BufferQueue.h>
-#include <gui/GraphicBufferAlloc.h>
#include <gui/Surface.h>
#include <cutils/properties.h>
#include <utils/misc.h>
diff --git a/include/media/MmapStreamInterface.h b/include/media/MmapStreamInterface.h
index 9f3731e..7dbc19e 100644
--- a/include/media/MmapStreamInterface.h
+++ b/include/media/MmapStreamInterface.h
@@ -75,6 +75,7 @@
/**
* Retrieve information on the mmap buffer used for audio samples transfer.
+ * Must be called before any other method after opening the stream or entering standby.
*
* \param[in] min_size_frames minimum buffer size requested. The actual buffer
* size returned in struct audio_mmap_buffer_info can be larger.
@@ -94,6 +95,7 @@
* \param[out] position address at which the mmap read/write position should be returned.
*
* \return OK if the position is successfully returned.
+ * NO_INIT in case of initialization error
* NOT_ENOUGH_DATA if the position cannot be retrieved
* INVALID_OPERATION if called before createMmapBuffer()
*/
@@ -106,6 +108,7 @@
* \param[in] client a Client struct describing the client starting on this stream.
* \param[out] handle unique handle for this instance. Used with stop().
* \return OK in case of success.
+ * NO_INIT in case of initialization error
* INVALID_OPERATION if called out of sequence
*/
virtual status_t start(const Client& client, audio_port_handle_t *handle) = 0;
@@ -116,10 +119,23 @@
*
* \param[in] handle unique handle allocated by start().
* \return OK in case of success.
+ * NO_INIT in case of initialization error
* INVALID_OPERATION if called out of sequence
*/
virtual status_t stop(audio_port_handle_t handle) = 0;
+ /**
+ * Put a stream operating in mmap mode into standby.
+ * Must be called after createMmapBuffer(). Cannot be called if any client is active.
+ * It is recommended to place a mmap stream into standby as often as possible when no client is
+ * active to save power.
+ *
+ * \return OK in case of success.
+ * NO_INIT in case of initialization error
+ * INVALID_OPERATION if called out of sequence
+ */
+ virtual status_t standby() = 0;
+
protected:
// Subclasses can not be constructed directly by clients.
MmapStreamInterface() {}
diff --git a/include/media/omx/1.0/Conversion.h b/include/media/omx/1.0/Conversion.h
index ee83713..f3f8441 100644
--- a/include/media/omx/1.0/Conversion.h
+++ b/include/media/omx/1.0/Conversion.h
@@ -191,6 +191,19 @@
}
/**
+ * \brief Convert `Return<Status>` to `binder::Status`.
+ *
+ * \param[in] t The source `Return<Status>`.
+ * \return The corresponding `binder::Status`.
+ */
+// convert: Return<Status> -> ::android::binder::Status
+inline ::android::binder::Status toBinderStatus(
+ Return<Status> const& t) {
+ return ::android::binder::Status::fromStatusT(
+ t.isOk() ? static_cast<status_t>(static_cast<Status>(t)) : UNKNOWN_ERROR);
+}
+
+/**
* \brief Convert `Return<Status>` to `status_t`. This is for legacy binder
* calls.
*
diff --git a/include/media/omx/1.0/WGraphicBufferSource.h b/include/media/omx/1.0/WGraphicBufferSource.h
index 7c80c2e..0ca5f44 100644
--- a/include/media/omx/1.0/WGraphicBufferSource.h
+++ b/include/media/omx/1.0/WGraphicBufferSource.h
@@ -48,7 +48,6 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
-
using ::android::IOMXNode;
/**
@@ -60,7 +59,7 @@
* - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
*/
-typedef ::android::IGraphicBufferSource LGraphicBufferSource;
+typedef ::android::binder::Status BnStatus;
typedef ::android::BnGraphicBufferSource BnGraphicBufferSource;
typedef ::android::hardware::media::omx::V1_0::IGraphicBufferSource
TGraphicBufferSource;
@@ -68,36 +67,19 @@
struct LWGraphicBufferSource : public BnGraphicBufferSource {
sp<TGraphicBufferSource> mBase;
LWGraphicBufferSource(sp<TGraphicBufferSource> const& base);
- ::android::binder::Status configure(
+ BnStatus configure(
const sp<IOMXNode>& omxNode, int32_t dataSpace) override;
- ::android::binder::Status setSuspend(bool suspend, int64_t timeUs) override;
- ::android::binder::Status setRepeatPreviousFrameDelayUs(
+ BnStatus setSuspend(bool suspend, int64_t timeUs) override;
+ BnStatus setRepeatPreviousFrameDelayUs(
int64_t repeatAfterUs) override;
- ::android::binder::Status setMaxFps(float maxFps) override;
- ::android::binder::Status setTimeLapseConfig(
+ BnStatus setMaxFps(float maxFps) override;
+ BnStatus setTimeLapseConfig(
int64_t timePerFrameUs, int64_t timePerCaptureUs) override;
- ::android::binder::Status setStartTimeUs(int64_t startTimeUs) override;
- ::android::binder::Status setStopTimeUs(int64_t stopTimeUs) override;
- ::android::binder::Status setColorAspects(int32_t aspects) override;
- ::android::binder::Status setTimeOffsetUs(int64_t timeOffsetsUs) override;
- ::android::binder::Status signalEndOfInputStream() override;
-};
-
-struct TWGraphicBufferSource : public TGraphicBufferSource {
- sp<LGraphicBufferSource> mBase;
- TWGraphicBufferSource(sp<LGraphicBufferSource> const& base);
- Return<void> configure(
- const sp<IOmxNode>& omxNode, Dataspace dataspace) override;
- Return<void> setSuspend(bool suspend, int64_t timeUs) override;
- Return<void> setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) override;
- Return<void> setMaxFps(float maxFps) override;
- Return<void> setTimeLapseConfig(
- int64_t timePerFrameUs, int64_t timePerCaptureUs) override;
- Return<void> setStartTimeUs(int64_t startTimeUs) override;
- Return<void> setStopTimeUs(int64_t stopTimeUs) override;
- Return<void> setColorAspects(const ColorAspects& aspects) override;
- Return<void> setTimeOffsetUs(int64_t timeOffsetUs) override;
- Return<void> signalEndOfInputStream() override;
+ BnStatus setStartTimeUs(int64_t startTimeUs) override;
+ BnStatus setStopTimeUs(int64_t stopTimeUs) override;
+ BnStatus setColorAspects(int32_t aspects) override;
+ BnStatus setTimeOffsetUs(int64_t timeOffsetsUs) override;
+ BnStatus signalEndOfInputStream() override;
};
} // namespace utils
diff --git a/include/media/omx/1.0/WOmx.h b/include/media/omx/1.0/WOmx.h
index 4aaf470..9268bd6 100644
--- a/include/media/omx/1.0/WOmx.h
+++ b/include/media/omx/1.0/WOmx.h
@@ -70,18 +70,6 @@
sp<::android::IGraphicBufferSource>* bufferSource) override;
};
-struct TWOmx : public IOmx {
- sp<IOMX> mBase;
- TWOmx(sp<IOMX> const& base);
- Return<void> listNodes(listNodes_cb _hidl_cb) override;
- Return<void> allocateNode(
- const hidl_string& name,
- const sp<IOmxObserver>& observer,
- allocateNode_cb _hidl_cb) override;
- Return<void> createInputSurface(createInputSurface_cb _hidl_cb) override;
-
-};
-
} // namespace utils
} // namespace V1_0
} // namespace omx
diff --git a/media/libmedia/omx/1.0/WGraphicBufferSource.cpp b/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
index 247c540..b4e2975 100644
--- a/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
+++ b/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#include <stagefright/foundation/ColorUtils.h>
-
#include <media/omx/1.0/WGraphicBufferSource.h>
#include <media/omx/1.0/WOmxNode.h>
#include <media/omx/1.0/Conversion.h>
@@ -27,14 +25,12 @@
namespace V1_0 {
namespace utils {
-using android::ColorUtils;
-
// LWGraphicBufferSource
LWGraphicBufferSource::LWGraphicBufferSource(
sp<TGraphicBufferSource> const& base) : mBase(base) {
}
-::android::binder::Status LWGraphicBufferSource::configure(
+BnStatus LWGraphicBufferSource::configure(
const sp<IOMXNode>& omxNode, int32_t dataSpace) {
sp<IOmxNode> hOmxNode = omxNode->getHalInterface();
return toBinderStatus(mBase->configure(
@@ -42,111 +38,51 @@
toHardwareDataspace(dataSpace)));
}
-::android::binder::Status LWGraphicBufferSource::setSuspend(
+BnStatus LWGraphicBufferSource::setSuspend(
bool suspend, int64_t timeUs) {
return toBinderStatus(mBase->setSuspend(suspend, timeUs));
}
-::android::binder::Status LWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
+BnStatus LWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
int64_t repeatAfterUs) {
return toBinderStatus(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
}
-::android::binder::Status LWGraphicBufferSource::setMaxFps(float maxFps) {
+BnStatus LWGraphicBufferSource::setMaxFps(float maxFps) {
return toBinderStatus(mBase->setMaxFps(maxFps));
}
-::android::binder::Status LWGraphicBufferSource::setTimeLapseConfig(
+BnStatus LWGraphicBufferSource::setTimeLapseConfig(
int64_t timePerFrameUs, int64_t timePerCaptureUs) {
return toBinderStatus(mBase->setTimeLapseConfig(
timePerFrameUs, timePerCaptureUs));
}
-::android::binder::Status LWGraphicBufferSource::setStartTimeUs(
+BnStatus LWGraphicBufferSource::setStartTimeUs(
int64_t startTimeUs) {
return toBinderStatus(mBase->setStartTimeUs(startTimeUs));
}
-::android::binder::Status LWGraphicBufferSource::setStopTimeUs(
+BnStatus LWGraphicBufferSource::setStopTimeUs(
int64_t stopTimeUs) {
return toBinderStatus(mBase->setStopTimeUs(stopTimeUs));
}
-::android::binder::Status LWGraphicBufferSource::setColorAspects(
+BnStatus LWGraphicBufferSource::setColorAspects(
int32_t aspects) {
return toBinderStatus(mBase->setColorAspects(
toHardwareColorAspects(aspects)));
}
-::android::binder::Status LWGraphicBufferSource::setTimeOffsetUs(
+BnStatus LWGraphicBufferSource::setTimeOffsetUs(
int64_t timeOffsetsUs) {
return toBinderStatus(mBase->setTimeOffsetUs(timeOffsetsUs));
}
-::android::binder::Status LWGraphicBufferSource::signalEndOfInputStream() {
+BnStatus LWGraphicBufferSource::signalEndOfInputStream() {
return toBinderStatus(mBase->signalEndOfInputStream());
}
-// TWGraphicBufferSource
-TWGraphicBufferSource::TWGraphicBufferSource(
- sp<LGraphicBufferSource> const& base) : mBase(base) {
-}
-
-Return<void> TWGraphicBufferSource::configure(
- const sp<IOmxNode>& omxNode, Dataspace dataspace) {
- mBase->configure(new LWOmxNode(omxNode), toRawDataspace(dataspace));
- return Void();
-}
-
-Return<void> TWGraphicBufferSource::setSuspend(
- bool suspend, int64_t timeUs) {
- mBase->setSuspend(suspend, timeUs);
- return Void();
-}
-
-Return<void> TWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
- int64_t repeatAfterUs) {
- mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs);
- return Void();
-}
-
-Return<void> TWGraphicBufferSource::setMaxFps(float maxFps) {
- mBase->setMaxFps(maxFps);
- return Void();
-}
-
-Return<void> TWGraphicBufferSource::setTimeLapseConfig(
- int64_t timePerFrameUs, int64_t timePerCaptureUs) {
- mBase->setTimeLapseConfig(timePerFrameUs, timePerCaptureUs);
- return Void();
-}
-
-Return<void> TWGraphicBufferSource::setStartTimeUs(int64_t startTimeUs) {
- mBase->setStartTimeUs(startTimeUs);
- return Void();
-}
-
-Return<void> TWGraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
- mBase->setStopTimeUs(stopTimeUs);
- return Void();
-}
-
-Return<void> TWGraphicBufferSource::setColorAspects(
- const ColorAspects& aspects) {
- mBase->setColorAspects(toCompactColorAspects(aspects));
- return Void();
-}
-
-Return<void> TWGraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
- mBase->setTimeOffsetUs(timeOffsetUs);
- return Void();
-}
-
-Return<void> TWGraphicBufferSource::signalEndOfInputStream() {
- mBase->signalEndOfInputStream();
- return Void();
-}
-
} // namespace utils
} // namespace V1_0
} // namespace omx
diff --git a/media/libmedia/omx/1.0/WOmx.cpp b/media/libmedia/omx/1.0/WOmx.cpp
index 39871f8..8e4e147 100644
--- a/media/libmedia/omx/1.0/WOmx.cpp
+++ b/media/libmedia/omx/1.0/WOmx.cpp
@@ -79,45 +79,6 @@
return transStatus == NO_ERROR ? fnStatus : transStatus;
}
-// TWOmx
-TWOmx::TWOmx(sp<IOMX> const& base) : mBase(base) {
-}
-
-Return<void> TWOmx::listNodes(listNodes_cb _hidl_cb) {
- List<IOMX::ComponentInfo> lList;
- Status status = toStatus(mBase->listNodes(&lList));
-
- hidl_vec<IOmx::ComponentInfo> tList;
- tList.resize(lList.size());
- size_t i = 0;
- for (auto const& lInfo : lList) {
- convertTo(&(tList[i++]), lInfo);
- }
- _hidl_cb(status, tList);
- return Void();
-}
-
-Return<void> TWOmx::allocateNode(
- const hidl_string& name,
- const sp<IOmxObserver>& observer,
- allocateNode_cb _hidl_cb) {
- sp<IOMXNode> omxNode;
- Status status = toStatus(mBase->allocateNode(
- name, new LWOmxObserver(observer), &omxNode));
- _hidl_cb(status, new TWOmxNode(omxNode));
- return Void();
-}
-
-Return<void> TWOmx::createInputSurface(createInputSurface_cb _hidl_cb) {
- sp<::android::IGraphicBufferProducer> lProducer;
- sp<::android::IGraphicBufferSource> lSource;
- status_t status = mBase->createInputSurface(&lProducer, &lSource);
- _hidl_cb(toStatus(status),
- new TWOmxBufferProducer(lProducer),
- new TWGraphicBufferSource(lSource));
- return Void();
-}
-
} // namespace utils
} // namespace V1_0
} // namespace omx
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 3b2a8a1..19c4d85 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -49,6 +49,7 @@
mSeekInProgress(false),
mPlayingTimeUs(0),
mLooper(new ALooper),
+ mPlayer(new NuPlayer(pid)),
mPlayerFlags(0),
mAnalyticsItem(NULL),
mAtEOS(false),
@@ -66,7 +67,6 @@
true, /* canCallJava */
PRIORITY_AUDIO);
- mPlayer = new NuPlayer(pid);
mLooper->registerHandler(mPlayer);
mPlayer->setDriver(this);
@@ -998,8 +998,6 @@
{
ALOGV("prepareDrm(%p) state: %d", this, mState);
- Mutex::Autolock autoLock(mLock);
-
// leaving the state verification for mediaplayer.cpp
status_t ret = mPlayer->prepareDrm(uuid, drmSessionId);
@@ -1012,8 +1010,6 @@
{
ALOGV("releaseDrm(%p) state: %d", this, mState);
- Mutex::Autolock autoLock(mLock);
-
// leaving the state verification for mediaplayer.cpp
status_t ret = mPlayer->releaseDrm();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index 972a348..082f71a 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -127,7 +127,7 @@
// <<<
sp<ALooper> mLooper;
- sp<NuPlayer> mPlayer;
+ const sp<NuPlayer> mPlayer;
sp<AudioSink> mAudioSink;
uint32_t mPlayerFlags;
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index de5ea9c..1d2a931 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -701,7 +701,13 @@
}
++sampleIndex;
- sampleTime += delta;
+ if (sampleTime > UINT32_MAX - delta) {
+ ALOGE("%u + %u would overflow, clamping",
+ sampleTime, delta);
+ sampleTime = UINT32_MAX;
+ } else {
+ sampleTime += delta;
+ }
}
}
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index 4f1ef30..d0d82b3 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -29,7 +29,6 @@
#include <ui/GraphicBuffer.h>
#include <gui/BufferItem.h>
#include <gui/ISurfaceComposer.h>
-#include <gui/IGraphicBufferAlloc.h>
#include <OMX_Component.h>
#include <utils/Log.h>
diff --git a/media/libstagefright/include/SurfaceMediaSource.h b/media/libstagefright/include/SurfaceMediaSource.h
index ca3a3bf..ae19a75 100644
--- a/media/libstagefright/include/SurfaceMediaSource.h
+++ b/media/libstagefright/include/SurfaceMediaSource.h
@@ -32,7 +32,6 @@
namespace android {
// ----------------------------------------------------------------------------
-class IGraphicBufferAlloc;
class String8;
class GraphicBuffer;
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk
index f70f13b..9cba3d0 100644
--- a/media/libstagefright/omx/Android.mk
+++ b/media/libstagefright/omx/Android.mk
@@ -4,6 +4,7 @@
LOCAL_SRC_FILES:= \
FrameDropper.cpp \
GraphicBufferSource.cpp \
+ BWGraphicBufferSource.cpp \
OMX.cpp \
OMXMaster.cpp \
OMXNodeInstance.cpp \
diff --git a/media/libstagefright/omx/BWGraphicBufferSource.cpp b/media/libstagefright/omx/BWGraphicBufferSource.cpp
new file mode 100644
index 0000000..4e0f6dd
--- /dev/null
+++ b/media/libstagefright/omx/BWGraphicBufferSource.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "BWGraphicBufferSource"
+
+#include <OMX_Component.h>
+#include <OMX_IndexExt.h>
+
+#include <media/OMXBuffer.h>
+#include <IOMX.h>
+
+#include "OMXUtils.h"
+#include "BWGraphicBufferSource.h"
+
+namespace android {
+
+static const OMX_U32 kPortIndexInput = 0;
+
+struct BWGraphicBufferSource::BWOmxNodeWrapper : public IOmxNodeWrapper {
+ sp<IOMXNode> mOMXNode;
+
+ BWOmxNodeWrapper(const sp<IOMXNode> &omxNode): mOMXNode(omxNode) {
+ }
+
+ virtual status_t emptyBuffer(
+ int32_t bufferId, uint32_t flags,
+ const sp<GraphicBuffer> &buffer,
+ int64_t timestamp, int fenceFd) override {
+ return mOMXNode->emptyBuffer(bufferId, buffer, flags, timestamp, fenceFd);
+ }
+
+ virtual void dispatchDataSpaceChanged(
+ int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override {
+ omx_message msg;
+ msg.type = omx_message::EVENT;
+ msg.fenceFd = -1;
+ msg.u.event_data.event = OMX_EventDataSpaceChanged;
+ msg.u.event_data.data1 = dataSpace;
+ msg.u.event_data.data2 = aspects;
+ msg.u.event_data.data3 = pixelFormat;
+ mOMXNode->dispatchMessage(msg);
+ }
+};
+
+struct BWGraphicBufferSource::BWOMXBufferSource : public BnOMXBufferSource {
+ sp<GraphicBufferSource> mSource;
+
+ BWOMXBufferSource(const sp<GraphicBufferSource> &source): mSource(source) {
+ }
+
+ Status onOmxExecuting() override {
+ return mSource->onOmxExecuting();
+ }
+
+ Status onOmxIdle() override {
+ return mSource->onOmxIdle();
+ }
+
+ Status onOmxLoaded() override {
+ return mSource->onOmxLoaded();
+ }
+
+ Status onInputBufferAdded(int bufferId) override {
+ return mSource->onInputBufferAdded(bufferId);
+ }
+
+ Status onInputBufferEmptied(
+ int bufferId, const OMXFenceParcelable& fenceParcel) override {
+ return mSource->onInputBufferEmptied(bufferId, fenceParcel.get());
+ }
+};
+
+BWGraphicBufferSource::BWGraphicBufferSource(
+ sp<GraphicBufferSource> const& base) :
+ mBase(base),
+ mOMXBufferSource(new BWOMXBufferSource(base)) {
+}
+
+::android::binder::Status BWGraphicBufferSource::configure(
+ const sp<IOMXNode>& omxNode, int32_t dataSpace) {
+ // Do setInputSurface() first, the node will try to enable metadata
+ // mode on input, and does necessary error checking. If this fails,
+ // we can't use this input surface on the node.
+ status_t err = omxNode->setInputSurface(mOMXBufferSource);
+ if (err != NO_ERROR) {
+ ALOGE("Unable to set input surface: %d", err);
+ return Status::fromStatusT(err);
+ }
+
+ // use consumer usage bits queried from encoder, but always add
+ // HW_VIDEO_ENCODER for backward compatibility.
+ uint32_t consumerUsage;
+ if (omxNode->getParameter(
+ (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
+ &consumerUsage, sizeof(consumerUsage)) != OK) {
+ consumerUsage = 0;
+ }
+
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+ def.nPortIndex = kPortIndexInput;
+
+ err = omxNode->getParameter(
+ OMX_IndexParamPortDefinition, &def, sizeof(def));
+ if (err != NO_ERROR) {
+ ALOGE("Failed to get port definition: %d", err);
+ return Status::fromStatusT(UNKNOWN_ERROR);
+ }
+
+ return Status::fromStatusT(mBase->configure(
+ new BWOmxNodeWrapper(omxNode),
+ dataSpace,
+ def.nBufferCountActual,
+ def.format.video.nFrameWidth,
+ def.format.video.nFrameHeight,
+ consumerUsage));
+}
+
+::android::binder::Status BWGraphicBufferSource::setSuspend(
+ bool suspend, int64_t timeUs) {
+ return Status::fromStatusT(mBase->setSuspend(suspend, timeUs));
+}
+
+::android::binder::Status BWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
+ int64_t repeatAfterUs) {
+ return Status::fromStatusT(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
+}
+
+::android::binder::Status BWGraphicBufferSource::setMaxFps(float maxFps) {
+ return Status::fromStatusT(mBase->setMaxFps(maxFps));
+}
+
+::android::binder::Status BWGraphicBufferSource::setTimeLapseConfig(
+ int64_t timePerFrameUs, int64_t timePerCaptureUs) {
+ return Status::fromStatusT(mBase->setTimeLapseConfig(
+ timePerFrameUs, timePerCaptureUs));
+}
+
+::android::binder::Status BWGraphicBufferSource::setStartTimeUs(
+ int64_t startTimeUs) {
+ return Status::fromStatusT(mBase->setStartTimeUs(startTimeUs));
+}
+
+::android::binder::Status BWGraphicBufferSource::setStopTimeUs(
+ int64_t stopTimeUs) {
+ return Status::fromStatusT(mBase->setStopTimeUs(stopTimeUs));
+}
+
+::android::binder::Status BWGraphicBufferSource::setColorAspects(
+ int32_t aspects) {
+ return Status::fromStatusT(mBase->setColorAspects(aspects));
+}
+
+::android::binder::Status BWGraphicBufferSource::setTimeOffsetUs(
+ int64_t timeOffsetsUs) {
+ return Status::fromStatusT(mBase->setTimeOffsetUs(timeOffsetsUs));
+}
+
+::android::binder::Status BWGraphicBufferSource::signalEndOfInputStream() {
+ return Status::fromStatusT(mBase->signalEndOfInputStream());
+}
+
+} // namespace android
diff --git a/media/libstagefright/omx/BWGraphicBufferSource.h b/media/libstagefright/omx/BWGraphicBufferSource.h
new file mode 100644
index 0000000..f1ce2af
--- /dev/null
+++ b/media/libstagefright/omx/BWGraphicBufferSource.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BWGRAPHIC_BUFFER_SOURCE_H_
+#define BWGRAPHIC_BUFFER_SOURCE_H_
+
+#include <binder/Binder.h>
+#include <binder/Status.h>
+#include <android/BnGraphicBufferSource.h>
+#include <android/BnOMXBufferSource.h>
+#include <IOMX.h>
+
+#include "GraphicBufferSource.h"
+#include "IOmxNodeWrapper.h"
+
+namespace android {
+
+using ::android::binder::Status;
+using ::android::BnGraphicBufferSource;
+using ::android::GraphicBufferSource;
+using ::android::IOMXNode;
+using ::android::sp;
+
+struct BWGraphicBufferSource : public BnGraphicBufferSource {
+ struct BWOMXBufferSource;
+ struct BWOmxNodeWrapper;
+
+ sp<GraphicBufferSource> mBase;
+ sp<IOMXBufferSource> mOMXBufferSource;
+
+ BWGraphicBufferSource(sp<GraphicBufferSource> const &base);
+
+ Status configure(
+ const sp<IOMXNode>& omxNode, int32_t dataSpace) override;
+ Status setSuspend(bool suspend, int64_t timeUs) override;
+ Status setRepeatPreviousFrameDelayUs(
+ int64_t repeatAfterUs) override;
+ Status setMaxFps(float maxFps) override;
+ Status setTimeLapseConfig(
+ int64_t timePerFrameUs, int64_t timePerCaptureUs) override;
+ Status setStartTimeUs(int64_t startTimeUs) override;
+ Status setStopTimeUs(int64_t stopTimeUs) override;
+ Status setColorAspects(int32_t aspects) override;
+ Status setTimeOffsetUs(int64_t timeOffsetsUs) override;
+ Status signalEndOfInputStream() override;
+};
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_MEDIA_OMX_V1_0_WGRAPHICBUFFERSOURCE_H
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index 2f457ac..793ecb8 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -41,37 +41,6 @@
namespace android {
-static const OMX_U32 kPortIndexInput = 0;
-
-class GraphicBufferSource::OmxBufferSource : public BnOMXBufferSource {
-public:
- GraphicBufferSource* mSource;
-
- OmxBufferSource(GraphicBufferSource* source): mSource(source) {
- }
-
- Status onOmxExecuting() override {
- return mSource->onOmxExecuting();
- }
-
- Status onOmxIdle() override {
- return mSource->onOmxIdle();
- }
-
- Status onOmxLoaded() override {
- return mSource->onOmxLoaded();
- }
-
- Status onInputBufferAdded(int bufferId) override {
- return mSource->onInputBufferAdded(bufferId);
- }
-
- Status onInputBufferEmptied(
- int bufferId, const OMXFenceParcelable& fenceParcel) override {
- return mSource->onInputBufferEmptied(bufferId, fenceParcel);
- }
-};
-
GraphicBufferSource::GraphicBufferSource() :
mInitCheck(UNKNOWN_ERROR),
mExecuting(false),
@@ -97,8 +66,7 @@
mTimePerFrameUs(-1ll),
mPrevCaptureUs(-1ll),
mPrevFrameUs(-1ll),
- mInputBufferTimeOffsetUs(0ll),
- mOmxBufferSource(new OmxBufferSource(this)) {
+ mInputBufferTimeOffsetUs(0ll) {
ALOGV("GraphicBufferSource");
String8 name("GraphicBufferSource");
@@ -122,7 +90,7 @@
return;
}
- memset(&mColorAspects, 0, sizeof(mColorAspects));
+ memset(&mColorAspectsPacked, 0, sizeof(mColorAspectsPacked));
CHECK(mInitCheck == NO_ERROR);
}
@@ -273,9 +241,7 @@
}
Status GraphicBufferSource::onInputBufferEmptied(
- int32_t bufferID, const OMXFenceParcelable &fenceParcel) {
- int fenceFd = fenceParcel.get();
-
+ int32_t bufferID, int fenceFd) {
Mutex::Autolock autoLock(mMutex);
if (!mExecuting) {
if (fenceFd >= 0) {
@@ -374,15 +340,7 @@
mLastDataSpace = dataSpace;
if (ColorUtils::convertDataSpaceToV0(dataSpace)) {
- omx_message msg;
- msg.type = omx_message::EVENT;
- msg.fenceFd = -1;
- msg.u.event_data.event = OMX_EventDataSpaceChanged;
- msg.u.event_data.data1 = mLastDataSpace;
- msg.u.event_data.data2 = ColorUtils::packToU32(mColorAspects);
- msg.u.event_data.data3 = pixelFormat;
-
- mOMXNode->dispatchMessage(msg);
+ mOMXNode->dispatchDataSpaceChanged(mLastDataSpace, mColorAspectsPacked, pixelFormat);
}
}
@@ -689,7 +647,7 @@
int fenceID = item.mFence->isValid() ? item.mFence->dup() : -1;
status_t err = mOMXNode->emptyBuffer(
- bufferID, buffer, OMX_BUFFERFLAG_ENDOFFRAME, codecTimeUs, fenceID);
+ bufferID, OMX_BUFFERFLAG_ENDOFFRAME, buffer, codecTimeUs, fenceID);
if (err != OK) {
ALOGW("WARNING: emptyGraphicBuffer failed: 0x%x", err);
@@ -721,10 +679,8 @@
CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
IOMX::buffer_id bufferID = codecBuffer.mBufferID;
- status_t err = mOMXNode->emptyBuffer(
- bufferID, (sp<GraphicBuffer>)NULL,
- OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS,
- 0 /* timestamp */, -1 /* fenceFd */);
+ status_t err = mOMXNode->emptyBuffer(bufferID,
+ OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS);
if (err != OK) {
ALOGW("emptyDirectBuffer EOS failed: 0x%x", err);
} else {
@@ -865,65 +821,38 @@
ALOG_ASSERT(false, "GraphicBufferSource can't consume sideband streams");
}
-Status GraphicBufferSource::configure(
- const sp<IOMXNode>& omxNode, int32_t dataSpace) {
+status_t GraphicBufferSource::configure(
+ const sp<IOmxNodeWrapper>& omxNode,
+ int32_t dataSpace,
+ int32_t bufferCount,
+ uint32_t frameWidth,
+ uint32_t frameHeight,
+ uint32_t consumerUsage) {
if (omxNode == NULL) {
- return Status::fromServiceSpecificError(BAD_VALUE);
+ return BAD_VALUE;
}
- // Do setInputSurface() first, the node will try to enable metadata
- // mode on input, and does necessary error checking. If this fails,
- // we can't use this input surface on the node.
- status_t err = omxNode->setInputSurface(mOmxBufferSource);
- if (err != NO_ERROR) {
- ALOGE("Unable to set input surface: %d", err);
- return Status::fromServiceSpecificError(err);
- }
-
- // use consumer usage bits queried from encoder, but always add
- // HW_VIDEO_ENCODER for backward compatibility.
- uint32_t consumerUsage;
- if (omxNode->getParameter(
- (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
- &consumerUsage, sizeof(consumerUsage)) != OK) {
- consumerUsage = 0;
- }
-
- OMX_PARAM_PORTDEFINITIONTYPE def;
- InitOMXParams(&def);
- def.nPortIndex = kPortIndexInput;
-
- err = omxNode->getParameter(
- OMX_IndexParamPortDefinition, &def, sizeof(def));
- if (err != NO_ERROR) {
- ALOGE("Failed to get port definition: %d", err);
- return Status::fromServiceSpecificError(UNKNOWN_ERROR);
- }
// Call setMaxAcquiredBufferCount without lock.
// setMaxAcquiredBufferCount could call back to onBuffersReleased
// if the buffer count change results in releasing of existing buffers,
// which would lead to deadlock.
- err = mConsumer->setMaxAcquiredBufferCount(def.nBufferCountActual);
+ status_t err = mConsumer->setMaxAcquiredBufferCount(bufferCount);
if (err != NO_ERROR) {
ALOGE("Unable to set BQ max acquired buffer count to %u: %d",
- def.nBufferCountActual, err);
- return Status::fromServiceSpecificError(err);
+ bufferCount, err);
+ return err;
}
{
Mutex::Autolock autoLock(mMutex);
mOMXNode = omxNode;
- err = mConsumer->setDefaultBufferSize(
- def.format.video.nFrameWidth,
- def.format.video.nFrameHeight);
+ err = mConsumer->setDefaultBufferSize(frameWidth, frameHeight);
if (err != NO_ERROR) {
ALOGE("Unable to set BQ default buffer size to %ux%u: %d",
- def.format.video.nFrameWidth,
- def.format.video.nFrameHeight,
- err);
- return Status::fromServiceSpecificError(err);
+ frameWidth, frameHeight, err);
+ return err;
}
consumerUsage |= GRALLOC_USAGE_HW_VIDEO_ENCODER;
@@ -957,17 +886,17 @@
mActionQueue.clear();
}
- return Status::ok();
+ return OK;
}
-Status GraphicBufferSource::setSuspend(bool suspend, int64_t suspendStartTimeUs) {
+status_t GraphicBufferSource::setSuspend(bool suspend, int64_t suspendStartTimeUs) {
ALOGV("setSuspend=%d at time %lld us", suspend, (long long)suspendStartTimeUs);
Mutex::Autolock autoLock(mMutex);
if (mStopTimeUs != -1) {
ALOGE("setSuspend failed as STOP action is pending");
- return Status::fromServiceSpecificError(INVALID_OPERATION);
+ return INVALID_OPERATION;
}
// Push the action to the queue.
@@ -977,12 +906,12 @@
if (suspendStartTimeUs > currentSystemTimeUs) {
ALOGE("setSuspend failed. %lld is larger than current system time %lld us",
(long long)suspendStartTimeUs, (long long)currentSystemTimeUs);
- return Status::fromServiceSpecificError(INVALID_OPERATION);
+ return INVALID_OPERATION;
}
if (mLastActionTimeUs != -1 && suspendStartTimeUs < mLastActionTimeUs) {
ALOGE("setSuspend failed. %lld is smaller than last action time %lld us",
(long long)suspendStartTimeUs, (long long)mLastActionTimeUs);
- return Status::fromServiceSpecificError(INVALID_OPERATION);
+ return INVALID_OPERATION;
}
mLastActionTimeUs = suspendStartTimeUs;
ActionItem action;
@@ -1007,7 +936,7 @@
releaseBuffer(item.mSlot, item.mFrameNumber, item.mFence);
}
- return Status::ok();
+ return OK;
} else {
mSuspended = false;
@@ -1023,54 +952,54 @@
}
}
}
- return Status::ok();
+ return OK;
}
-Status GraphicBufferSource::setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) {
+status_t GraphicBufferSource::setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) {
ALOGV("setRepeatPreviousFrameDelayUs: delayUs=%lld", (long long)repeatAfterUs);
Mutex::Autolock autoLock(mMutex);
if (mExecuting || repeatAfterUs <= 0ll) {
- return Status::fromServiceSpecificError(INVALID_OPERATION);
+ return INVALID_OPERATION;
}
mRepeatAfterUs = repeatAfterUs;
- return Status::ok();
+ return OK;
}
-Status GraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
+status_t GraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
Mutex::Autolock autoLock(mMutex);
// timeOffsetUs must be negative for adjustment.
if (timeOffsetUs >= 0ll) {
- return Status::fromServiceSpecificError(INVALID_OPERATION);
+ return INVALID_OPERATION;
}
mInputBufferTimeOffsetUs = timeOffsetUs;
- return Status::ok();
+ return OK;
}
-Status GraphicBufferSource::setMaxFps(float maxFps) {
+status_t GraphicBufferSource::setMaxFps(float maxFps) {
ALOGV("setMaxFps: maxFps=%lld", (long long)maxFps);
Mutex::Autolock autoLock(mMutex);
if (mExecuting) {
- return Status::fromServiceSpecificError(INVALID_OPERATION);
+ return INVALID_OPERATION;
}
mFrameDropper = new FrameDropper();
status_t err = mFrameDropper->setMaxFrameRate(maxFps);
if (err != OK) {
mFrameDropper.clear();
- return Status::fromServiceSpecificError(err);
+ return err;
}
- return Status::ok();
+ return OK;
}
-Status GraphicBufferSource::setStartTimeUs(int64_t skipFramesBeforeUs) {
+status_t GraphicBufferSource::setStartTimeUs(int64_t skipFramesBeforeUs) {
ALOGV("setStartTimeUs: skipFramesBeforeUs=%lld", (long long)skipFramesBeforeUs);
Mutex::Autolock autoLock(mMutex);
@@ -1078,16 +1007,16 @@
mSkipFramesBeforeNs =
(skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll;
- return Status::ok();
+ return OK;
}
-Status GraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
+status_t GraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
ALOGV("setStopTimeUs: %lld us", (long long)stopTimeUs);
Mutex::Autolock autoLock(mMutex);
if (mStopTimeUs != -1) {
// Ignore if stop time has already been set
- return Status::ok();
+ return OK;
}
// stopTimeUs must be smaller or equal to current systemTime.
@@ -1095,12 +1024,12 @@
if (stopTimeUs > currentSystemTimeUs) {
ALOGE("setStopTimeUs failed. %lld is larger than current system time %lld us",
(long long)stopTimeUs, (long long)currentSystemTimeUs);
- return Status::fromServiceSpecificError(INVALID_OPERATION);
+ return INVALID_OPERATION;
}
if (mLastActionTimeUs != -1 && stopTimeUs < mLastActionTimeUs) {
ALOGE("setSuspend failed. %lld is smaller than last action time %lld us",
(long long)stopTimeUs, (long long)mLastActionTimeUs);
- return Status::fromServiceSpecificError(INVALID_OPERATION);
+ return INVALID_OPERATION;
}
mLastActionTimeUs = stopTimeUs;
ActionItem action;
@@ -1108,45 +1037,46 @@
action.mActionTimeUs = stopTimeUs;
mActionQueue.push_back(action);
mStopTimeUs = stopTimeUs;
- return Status::ok();
+ return OK;
}
-Status GraphicBufferSource::setTimeLapseConfig(int64_t timePerFrameUs, int64_t timePerCaptureUs) {
+status_t GraphicBufferSource::setTimeLapseConfig(int64_t timePerFrameUs, int64_t timePerCaptureUs) {
ALOGV("setTimeLapseConfig: timePerFrameUs=%lld, timePerCaptureUs=%lld",
(long long)timePerFrameUs, (long long)timePerCaptureUs);
Mutex::Autolock autoLock(mMutex);
if (mExecuting || timePerFrameUs <= 0ll || timePerCaptureUs <= 0ll) {
- return Status::fromServiceSpecificError(INVALID_OPERATION);
+ return INVALID_OPERATION;
}
mTimePerFrameUs = timePerFrameUs;
mTimePerCaptureUs = timePerCaptureUs;
- return Status::ok();
+ return OK;
}
-Status GraphicBufferSource::setColorAspects(int32_t aspectsPacked) {
+status_t GraphicBufferSource::setColorAspects(int32_t aspectsPacked) {
Mutex::Autolock autoLock(mMutex);
- mColorAspects = ColorUtils::unpackToColorAspects(aspectsPacked);
+ mColorAspectsPacked = aspectsPacked;
+ ColorAspects colorAspects = ColorUtils::unpackToColorAspects(aspectsPacked);
ALOGD("requesting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s))",
- mColorAspects.mRange, asString(mColorAspects.mRange),
- mColorAspects.mPrimaries, asString(mColorAspects.mPrimaries),
- mColorAspects.mMatrixCoeffs, asString(mColorAspects.mMatrixCoeffs),
- mColorAspects.mTransfer, asString(mColorAspects.mTransfer));
+ colorAspects.mRange, asString(colorAspects.mRange),
+ colorAspects.mPrimaries, asString(colorAspects.mPrimaries),
+ colorAspects.mMatrixCoeffs, asString(colorAspects.mMatrixCoeffs),
+ colorAspects.mTransfer, asString(colorAspects.mTransfer));
- return Status::ok();
+ return OK;
}
-Status GraphicBufferSource::signalEndOfInputStream() {
+status_t GraphicBufferSource::signalEndOfInputStream() {
Mutex::Autolock autoLock(mMutex);
ALOGV("signalEndOfInputStream: exec=%d avail=%zu eos=%d",
mExecuting, mNumFramesAvailable, mEndOfStream);
if (mEndOfStream) {
ALOGE("EOS was already signaled");
- return Status::fromStatusT(INVALID_OPERATION);
+ return INVALID_OPERATION;
}
// Set the end-of-stream flag. If no frames are pending from the
@@ -1163,7 +1093,7 @@
submitEndOfInputStream_l();
}
- return Status::ok();
+ return OK;
}
void GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) {
diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h
index 475548e..371c5ed 100644
--- a/media/libstagefright/omx/GraphicBufferSource.h
+++ b/media/libstagefright/omx/GraphicBufferSource.h
@@ -32,6 +32,8 @@
#include <android/BnGraphicBufferSource.h>
#include <android/BnOMXBufferSource.h>
+#include "IOmxNodeWrapper.h"
+
namespace android {
using ::android::binder::Status;
@@ -54,8 +56,7 @@
* before the codec is in the "executing" state, so we need to queue
* things up until we're ready to go.
*/
-class GraphicBufferSource : public BnGraphicBufferSource,
- public BufferQueue::ConsumerListener {
+class GraphicBufferSource : public BufferQueue::ConsumerListener {
public:
GraphicBufferSource();
@@ -95,24 +96,30 @@
// Called from OnEmptyBufferDone. If we have a BQ buffer available,
// fill it with a new frame of data; otherwise, just mark it as available.
Status onInputBufferEmptied(
- int32_t bufferID, const OMXFenceParcelable& fenceParcel);
+ int32_t bufferID, int fenceFd);
// Configure the buffer source to be used with an OMX node with the default
// data space.
- Status configure(const sp<IOMXNode>& omxNode, int32_t dataSpace) override;
+ status_t configure(
+ const sp<IOmxNodeWrapper> &omxNode,
+ int32_t dataSpace,
+ int32_t bufferCount,
+ uint32_t frameWidth,
+ uint32_t frameHeight,
+ uint32_t consumerUsage);
// This is called after the last input frame has been submitted or buffer
// timestamp is greater or equal than stopTimeUs. We need to submit an empty
// buffer with the EOS flag set. If we don't have a codec buffer ready,
// we just set the mEndOfStream flag.
- Status signalEndOfInputStream() override;
+ status_t signalEndOfInputStream();
// If suspend is true, all incoming buffers (including those currently
// in the BufferQueue) with timestamp larger than timeUs will be discarded
// until the suspension is lifted. If suspend is false, all incoming buffers
// including those currently in the BufferQueue) with timestamp larger than
// timeUs will be processed. timeUs uses SYSTEM_TIME_MONOTONIC time base.
- Status setSuspend(bool suspend, int64_t timeUs) override;
+ status_t setSuspend(bool suspend, int64_t timeUs);
// Specifies the interval after which we requeue the buffer previously
// queued to the encoder. This is useful in the case of surface flinger
@@ -121,30 +128,30 @@
// the decoder on the remote end would be unable to decode the latest frame.
// This API must be called before transitioning the encoder to "executing"
// state and once this behaviour is specified it cannot be reset.
- Status setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) override;
+ status_t setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs);
// Sets the input buffer timestamp offset.
// When set, the sample's timestamp will be adjusted with the timeOffsetUs.
- Status setTimeOffsetUs(int64_t timeOffsetUs) override;
+ status_t setTimeOffsetUs(int64_t timeOffsetUs);
// When set, the max frame rate fed to the encoder will be capped at maxFps.
- Status setMaxFps(float maxFps) override;
+ status_t setMaxFps(float maxFps);
// Sets the time lapse (or slow motion) parameters.
// When set, the sample's timestamp will be modified to playback framerate,
// and capture timestamp will be modified to capture rate.
- Status setTimeLapseConfig(int64_t timePerFrameUs, int64_t timePerCaptureUs) override;
+ status_t setTimeLapseConfig(int64_t timePerFrameUs, int64_t timePerCaptureUs);
// Sets the start time us (in system time), samples before which should
// be dropped and not submitted to encoder
- Status setStartTimeUs(int64_t startTimeUs) override;
+ status_t setStartTimeUs(int64_t startTimeUs);
// Sets the stop time us (in system time), samples after which should be dropped
// and not submitted to encoder. timeUs uses SYSTEM_TIME_MONOTONIC time base.
- Status setStopTimeUs(int64_t stopTimeUs) override;
+ status_t setStopTimeUs(int64_t stopTimeUs);
// Sets the desired color aspects, e.g. to be used when producer does not specify a dataspace.
- Status setColorAspects(int32_t aspectsPacked) override;
+ status_t setColorAspects(int32_t aspectsPacked);
protected:
// BufferQueue::ConsumerListener interface, called when a new frame of
@@ -229,8 +236,8 @@
// Used to report constructor failure.
status_t mInitCheck;
- // Pointer back to the IOMXNode that created us. We send buffers here.
- sp<IOMXNode> mOMXNode;
+ // Pointer back to the Omx node that created us. We send buffers here.
+ sp<IOmxNodeWrapper> mOMXNode;
// Set by omxExecuting() / omxIdling().
bool mExecuting;
@@ -328,10 +335,7 @@
int64_t mInputBufferTimeOffsetUs;
- ColorAspects mColorAspects;
-
- class OmxBufferSource;
- sp<OmxBufferSource> mOmxBufferSource;
+ int32_t mColorAspectsPacked;
void onMessageReceived(const sp<AMessage> &msg);
diff --git a/media/libstagefright/omx/IOmxNodeWrapper.h b/media/libstagefright/omx/IOmxNodeWrapper.h
new file mode 100644
index 0000000..cd44e67
--- /dev/null
+++ b/media/libstagefright/omx/IOmxNodeWrapper.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IOMX_NODE_WRAPPER_SOURCE_H_
+#define IOMX_NODE_WRAPPER_SOURCE_H_
+
+#include <utils/RefBase.h>
+#include <utils/StrongPointer.h>
+#include <ui/GraphicBuffer.h>
+
+#include <stdint.h>
+
+namespace android {
+
+struct IOmxNodeWrapper : public RefBase {
+ virtual status_t emptyBuffer(
+ int32_t bufferId, uint32_t flags,
+ const sp<GraphicBuffer> &buffer = nullptr,
+ int64_t timestamp = 0, int fenceFd = -1) = 0;
+ virtual void dispatchDataSpaceChanged(
+ int32_t dataSpace, int32_t aspects, int32_t pixelFormat) = 0;
+};
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_MEDIA_OMX_V1_0_WGRAPHICBUFFERSOURCE_H
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 80c125c..bf1418f 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -27,7 +27,7 @@
#include "../include/OMXNodeInstance.h"
#include <media/stagefright/foundation/ADebug.h>
-#include "GraphicBufferSource.h"
+#include "BWGraphicBufferSource.h"
#include "OMXMaster.h"
#include "OMXUtils.h"
@@ -174,7 +174,7 @@
}
*bufferProducer = graphicBufferSource->getIGraphicBufferProducer();
- *bufferSource = graphicBufferSource;
+ *bufferSource = new BWGraphicBufferSource(graphicBufferSource);
return OK;
}
diff --git a/media/libstagefright/omx/hal/1.0/impl/Android.mk b/media/libstagefright/omx/hal/1.0/impl/Android.mk
index 09424b5..79cb1fa 100644
--- a/media/libstagefright/omx/hal/1.0/impl/Android.mk
+++ b/media/libstagefright/omx/hal/1.0/impl/Android.mk
@@ -4,7 +4,6 @@
LOCAL_MODULE := android.hardware.media.omx@1.0-impl
LOCAL_SRC_FILES := \
WGraphicBufferSource.cpp \
- WOmx.cpp \
WOmxBufferProducer.cpp \
WOmxBufferSource.cpp \
WOmxNode.cpp \
diff --git a/media/libstagefright/omx/hal/1.0/impl/Conversion.h b/media/libstagefright/omx/hal/1.0/impl/Conversion.h
index 117d1c8..a6fed2e 100644
--- a/media/libstagefright/omx/hal/1.0/impl/Conversion.h
+++ b/media/libstagefright/omx/hal/1.0/impl/Conversion.h
@@ -611,6 +611,37 @@
}
/**
+ * \brief Wrap `GraphicBuffer` in `CodecBuffer`.
+ *
+ * \param[out] t The wrapper of type `CodecBuffer`.
+ * \param[in] l The source `GraphicBuffer`.
+ */
+// wrap: OMXBuffer -> CodecBuffer
+inline CodecBuffer *wrapAs(CodecBuffer *t, sp<GraphicBuffer> const& graphicBuffer) {
+ t->sharedMemory = hidl_memory();
+ t->nativeHandle = hidl_handle();
+ t->type = CodecBuffer::Type::ANW_BUFFER;
+ if (graphicBuffer == nullptr) {
+ t->attr.anwBuffer.width = 0;
+ t->attr.anwBuffer.height = 0;
+ t->attr.anwBuffer.stride = 0;
+ t->attr.anwBuffer.format = static_cast<PixelFormat>(1);
+ t->attr.anwBuffer.layerCount = 0;
+ t->attr.anwBuffer.usage = 0;
+ return t;
+ }
+ t->attr.anwBuffer.width = graphicBuffer->getWidth();
+ t->attr.anwBuffer.height = graphicBuffer->getHeight();
+ t->attr.anwBuffer.stride = graphicBuffer->getStride();
+ t->attr.anwBuffer.format = static_cast<PixelFormat>(
+ graphicBuffer->getPixelFormat());
+ t->attr.anwBuffer.layerCount = graphicBuffer->getLayerCount();
+ t->attr.anwBuffer.usage = graphicBuffer->getUsage();
+ t->nativeHandle = graphicBuffer->handle;
+ return t;
+}
+
+/**
* \brief Wrap `OMXBuffer` in `CodecBuffer`.
*
* \param[out] t The wrapper of type `CodecBuffer`.
@@ -642,24 +673,7 @@
return false;
}
case OMXBuffer::kBufferTypeANWBuffer: {
- t->type = CodecBuffer::Type::ANW_BUFFER;
- if (l.mGraphicBuffer == nullptr) {
- t->attr.anwBuffer.width = 0;
- t->attr.anwBuffer.height = 0;
- t->attr.anwBuffer.stride = 0;
- t->attr.anwBuffer.format = static_cast<PixelFormat>(1);
- t->attr.anwBuffer.layerCount = 0;
- t->attr.anwBuffer.usage = 0;
- return true;
- }
- t->attr.anwBuffer.width = l.mGraphicBuffer->getWidth();
- t->attr.anwBuffer.height = l.mGraphicBuffer->getHeight();
- t->attr.anwBuffer.stride = l.mGraphicBuffer->getStride();
- t->attr.anwBuffer.format = static_cast<PixelFormat>(
- l.mGraphicBuffer->getPixelFormat());
- t->attr.anwBuffer.layerCount = l.mGraphicBuffer->getLayerCount();
- t->attr.anwBuffer.usage = l.mGraphicBuffer->getUsage();
- t->nativeHandle = l.mGraphicBuffer->handle;
+ wrapAs(t, l.mGraphicBuffer);
return true;
}
case OMXBuffer::kBufferTypeNativeHandle: {
diff --git a/media/libstagefright/omx/hal/1.0/impl/Omx.cpp b/media/libstagefright/omx/hal/1.0/impl/Omx.cpp
index a9f29e9..0ef7c8c 100644
--- a/media/libstagefright/omx/hal/1.0/impl/Omx.cpp
+++ b/media/libstagefright/omx/hal/1.0/impl/Omx.cpp
@@ -123,7 +123,6 @@
Return<void> Omx::createInputSurface(createInputSurface_cb _hidl_cb) {
sp<::android::IGraphicBufferProducer> bufferProducer;
- sp<::android::IGraphicBufferSource> bufferSource;
sp<GraphicBufferSource> graphicBufferSource = new GraphicBufferSource();
status_t err = graphicBufferSource->initCheck();
@@ -135,11 +134,10 @@
return Void();
}
bufferProducer = graphicBufferSource->getIGraphicBufferProducer();
- bufferSource = graphicBufferSource;
_hidl_cb(toStatus(OK),
new TWOmxBufferProducer(bufferProducer),
- new TWGraphicBufferSource(bufferSource));
+ new TWGraphicBufferSource(graphicBufferSource));
return Void();
}
diff --git a/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.cpp b/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.cpp
index 884e87b..13e1f2f 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.cpp
+++ b/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.cpp
@@ -14,8 +14,15 @@
* limitations under the License.
*/
-#include <stagefright/foundation/ColorUtils.h>
+//#define LOG_NDEBUG 0
+#define LOG_TAG "TWGraphicBufferSource"
+#include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+#include <OMX_Component.h>
+#include <OMX_IndexExt.h>
+
+#include "omx/OMXUtils.h"
#include "WGraphicBufferSource.h"
#include "WOmxNode.h"
#include "Conversion.h"
@@ -27,122 +34,183 @@
namespace V1_0 {
namespace implementation {
-using android::ColorUtils;
+static const OMX_U32 kPortIndexInput = 0;
-// LWGraphicBufferSource
-LWGraphicBufferSource::LWGraphicBufferSource(
- sp<TGraphicBufferSource> const& base) : mBase(base) {
-}
+struct TWGraphicBufferSource::TWOmxNodeWrapper : public IOmxNodeWrapper {
+ sp<IOmxNode> mOmxNode;
-::android::binder::Status LWGraphicBufferSource::configure(
- const sp<IOMXNode>& omxNode, int32_t dataSpace) {
- return toBinderStatus(mBase->configure(
- new TWOmxNode(omxNode), toHardwareDataspace(dataSpace)));
-}
+ TWOmxNodeWrapper(const sp<IOmxNode> &omxNode): mOmxNode(omxNode) {
+ }
-::android::binder::Status LWGraphicBufferSource::setSuspend(
- bool suspend, int64_t timeUs) {
- return toBinderStatus(mBase->setSuspend(suspend, timeUs));
-}
+ virtual status_t emptyBuffer(
+ int32_t bufferId, uint32_t flags,
+ const sp<GraphicBuffer> &buffer,
+ int64_t timestamp, int fenceFd) override {
+ CodecBuffer tBuffer;
+ return toStatusT(mOmxNode->emptyBuffer(
+ bufferId,
+ *wrapAs(&tBuffer, buffer),
+ flags,
+ toRawTicks(timestamp),
+ native_handle_create_from_fd(fenceFd)));
+ }
-::android::binder::Status LWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
- int64_t repeatAfterUs) {
- return toBinderStatus(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
-}
+ virtual void dispatchDataSpaceChanged(
+ int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override {
+ Message tMsg;
+ tMsg.type = Message::Type::EVENT;
+ tMsg.fence = native_handle_create(0, 0);
+ tMsg.data.eventData.event = uint32_t(OMX_EventDataSpaceChanged);
+ tMsg.data.eventData.data1 = dataSpace;
+ tMsg.data.eventData.data2 = aspects;
+ tMsg.data.eventData.data3 = pixelFormat;
+ mOmxNode->dispatchMessage(tMsg);
+ }
+};
-::android::binder::Status LWGraphicBufferSource::setMaxFps(float maxFps) {
- return toBinderStatus(mBase->setMaxFps(maxFps));
-}
+struct TWGraphicBufferSource::TWOmxBufferSource : public IOmxBufferSource {
+ sp<GraphicBufferSource> mSource;
-::android::binder::Status LWGraphicBufferSource::setTimeLapseConfig(
- int64_t timePerFrameUs, int64_t timePerCaptureUs) {
- return toBinderStatus(mBase->setTimeLapseConfig(
- timePerFrameUs, timePerCaptureUs));
-}
+ TWOmxBufferSource(const sp<GraphicBufferSource> &source): mSource(source) {
+ }
-::android::binder::Status LWGraphicBufferSource::setStartTimeUs(
- int64_t startTimeUs) {
- return toBinderStatus(mBase->setStartTimeUs(startTimeUs));
-}
+ Return<void> onOmxExecuting() override {
+ mSource->onOmxExecuting();
+ return Void();
+ }
-::android::binder::Status LWGraphicBufferSource::setStopTimeUs(
- int64_t stopTimeUs) {
- return toBinderStatus(mBase->setStopTimeUs(stopTimeUs));
-}
+ Return<void> onOmxIdle() override {
+ mSource->onOmxIdle();
+ return Void();
+ }
-::android::binder::Status LWGraphicBufferSource::setColorAspects(
- int32_t aspects) {
- return toBinderStatus(mBase->setColorAspects(
- toHardwareColorAspects(aspects)));
-}
+ Return<void> onOmxLoaded() override {
+ mSource->onOmxLoaded();
+ return Void();
+ }
-::android::binder::Status LWGraphicBufferSource::setTimeOffsetUs(
- int64_t timeOffsetsUs) {
- return toBinderStatus(mBase->setTimeOffsetUs(timeOffsetsUs));
-}
+ Return<void> onInputBufferAdded(uint32_t bufferId) override {
+ mSource->onInputBufferAdded(static_cast<int32_t>(bufferId));
+ return Void();
+ }
-::android::binder::Status LWGraphicBufferSource::signalEndOfInputStream() {
- return toBinderStatus(mBase->signalEndOfInputStream());
-}
+ Return<void> onInputBufferEmptied(
+ uint32_t bufferId, hidl_handle const& tFence) override {
+ mSource->onInputBufferEmptied(
+ static_cast<int32_t>(bufferId),
+ native_handle_read_fd(tFence));
+ return Void();
+ }
+};
// TWGraphicBufferSource
TWGraphicBufferSource::TWGraphicBufferSource(
- sp<LGraphicBufferSource> const& base) : mBase(base) {
+ sp<GraphicBufferSource> const& base) :
+ mBase(base),
+ mOmxBufferSource(new TWOmxBufferSource(base)) {
}
-Return<void> TWGraphicBufferSource::configure(
+Return<Status> TWGraphicBufferSource::configure(
const sp<IOmxNode>& omxNode, Dataspace dataspace) {
- mBase->configure(new LWOmxNode(omxNode), toRawDataspace(dataspace));
- return Void();
+ if (omxNode == NULL) {
+ return toStatus(BAD_VALUE);
+ }
+
+ // Do setInputSurface() first, the node will try to enable metadata
+ // mode on input, and does necessary error checking. If this fails,
+ // we can't use this input surface on the node.
+ Return<Status> err(omxNode->setInputSurface(mOmxBufferSource));
+ status_t fnStatus = toStatusT(err);
+ if (fnStatus != NO_ERROR) {
+ ALOGE("Unable to set input surface: %d", fnStatus);
+ return err;
+ }
+
+ // use consumer usage bits queried from encoder, but always add
+ // HW_VIDEO_ENCODER for backward compatibility.
+ uint32_t consumerUsage;
+ void *_params = &consumerUsage;
+ uint8_t *params = static_cast<uint8_t*>(_params);
+ fnStatus = UNKNOWN_ERROR;
+ IOmxNode::getParameter_cb _hidl_cb(
+ [&fnStatus, ¶ms](Status status, hidl_vec<uint8_t> const& outParams) {
+ fnStatus = toStatusT(status);
+ std::copy(
+ outParams.data(),
+ outParams.data() + outParams.size(),
+ params);
+ });
+ omxNode->getParameter(
+ static_cast<uint32_t>(OMX_IndexParamConsumerUsageBits),
+ inHidlBytes(&consumerUsage, sizeof(consumerUsage)),
+ _hidl_cb);
+ if (fnStatus != OK) {
+ consumerUsage = 0;
+ }
+
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+ def.nPortIndex = kPortIndexInput;
+
+ _params = &def;
+ params = static_cast<uint8_t*>(_params);
+ omxNode->getParameter(
+ static_cast<uint32_t>(OMX_IndexParamPortDefinition),
+ inHidlBytes(&def, sizeof(def)),
+ _hidl_cb);
+ if (fnStatus != NO_ERROR) {
+ ALOGE("Failed to get port definition: %d", fnStatus);
+ return toStatus(fnStatus);
+ }
+
+
+ return toStatus(mBase->configure(
+ new TWOmxNodeWrapper(omxNode),
+ toRawDataspace(dataspace),
+ def.nBufferCountActual,
+ def.format.video.nFrameWidth,
+ def.format.video.nFrameHeight,
+ consumerUsage));
}
-Return<void> TWGraphicBufferSource::setSuspend(
+Return<Status> TWGraphicBufferSource::setSuspend(
bool suspend, int64_t timeUs) {
- mBase->setSuspend(suspend, timeUs);
- return Void();
+ return toStatus(mBase->setSuspend(suspend, timeUs));
}
-Return<void> TWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
+Return<Status> TWGraphicBufferSource::setRepeatPreviousFrameDelayUs(
int64_t repeatAfterUs) {
- mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs);
- return Void();
+ return toStatus(mBase->setRepeatPreviousFrameDelayUs(repeatAfterUs));
}
-Return<void> TWGraphicBufferSource::setMaxFps(float maxFps) {
- mBase->setMaxFps(maxFps);
- return Void();
+Return<Status> TWGraphicBufferSource::setMaxFps(float maxFps) {
+ return toStatus(mBase->setMaxFps(maxFps));
}
-Return<void> TWGraphicBufferSource::setTimeLapseConfig(
+Return<Status> TWGraphicBufferSource::setTimeLapseConfig(
int64_t timePerFrameUs, int64_t timePerCaptureUs) {
- mBase->setTimeLapseConfig(timePerFrameUs, timePerCaptureUs);
- return Void();
+ return toStatus(mBase->setTimeLapseConfig(timePerFrameUs, timePerCaptureUs));
}
-Return<void> TWGraphicBufferSource::setStartTimeUs(int64_t startTimeUs) {
- mBase->setStartTimeUs(startTimeUs);
- return Void();
+Return<Status> TWGraphicBufferSource::setStartTimeUs(int64_t startTimeUs) {
+ return toStatus(mBase->setStartTimeUs(startTimeUs));
}
-Return<void> TWGraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
- mBase->setStopTimeUs(stopTimeUs);
- return Void();
+Return<Status> TWGraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
+ return toStatus(mBase->setStopTimeUs(stopTimeUs));
}
-Return<void> TWGraphicBufferSource::setColorAspects(
+Return<Status> TWGraphicBufferSource::setColorAspects(
const ColorAspects& aspects) {
- mBase->setColorAspects(toCompactColorAspects(aspects));
- return Void();
+ return toStatus(mBase->setColorAspects(toCompactColorAspects(aspects)));
}
-Return<void> TWGraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
- mBase->setTimeOffsetUs(timeOffsetUs);
- return Void();
+Return<Status> TWGraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
+ return toStatus(mBase->setTimeOffsetUs(timeOffsetUs));
}
-Return<void> TWGraphicBufferSource::signalEndOfInputStream() {
- mBase->signalEndOfInputStream();
- return Void();
+Return<Status> TWGraphicBufferSource::signalEndOfInputStream() {
+ return toStatus(mBase->signalEndOfInputStream());
}
} // namespace implementation
diff --git a/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.h b/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.h
index bd60c46..8cf11ca 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.h
+++ b/media/libstagefright/omx/hal/1.0/impl/WGraphicBufferSource.h
@@ -20,15 +20,16 @@
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
-#include <media/IOMX.h>
-#include <binder/Binder.h>
-
+#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
#include <android/hardware/graphics/common/1.0/types.h>
#include <android/hardware/media/omx/1.0/IOmxNode.h>
#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
#include <android/BnGraphicBufferSource.h>
+#include "../../../GraphicBufferSource.h"
+
namespace android {
namespace hardware {
namespace media {
@@ -36,10 +37,12 @@
namespace V1_0 {
namespace implementation {
+using ::android::GraphicBufferSource;
using ::android::hardware::graphics::common::V1_0::Dataspace;
using ::android::hardware::media::omx::V1_0::ColorAspects;
using ::android::hardware::media::omx::V1_0::IGraphicBufferSource;
using ::android::hardware::media::omx::V1_0::IOmxNode;
+using ::android::hardware::media::omx::V1_0::Status;
using ::android::hidl::base::V1_0::IBase;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_memory;
@@ -60,44 +63,28 @@
* - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
*/
-typedef ::android::IGraphicBufferSource LGraphicBufferSource;
-typedef ::android::BnGraphicBufferSource BnGraphicBufferSource;
typedef ::android::hardware::media::omx::V1_0::IGraphicBufferSource
TGraphicBufferSource;
-struct LWGraphicBufferSource : public BnGraphicBufferSource {
- sp<TGraphicBufferSource> mBase;
- LWGraphicBufferSource(sp<TGraphicBufferSource> const& base);
- ::android::binder::Status configure(
- const sp<IOMXNode>& omxNode, int32_t dataSpace) override;
- ::android::binder::Status setSuspend(bool suspend, int64_t timeUs) override;
- ::android::binder::Status setRepeatPreviousFrameDelayUs(
- int64_t repeatAfterUs) override;
- ::android::binder::Status setMaxFps(float maxFps) override;
- ::android::binder::Status setTimeLapseConfig(
- int64_t timePerFrameUs, int64_t timePerCaptureUs) override;
- ::android::binder::Status setStartTimeUs(int64_t startTimeUs) override;
- ::android::binder::Status setStopTimeUs(int64_t stopTimeUs) override;
- ::android::binder::Status setColorAspects(int32_t aspects) override;
- ::android::binder::Status setTimeOffsetUs(int64_t timeOffsetsUs) override;
- ::android::binder::Status signalEndOfInputStream() override;
-};
-
struct TWGraphicBufferSource : public TGraphicBufferSource {
- sp<LGraphicBufferSource> mBase;
- TWGraphicBufferSource(sp<LGraphicBufferSource> const& base);
- Return<void> configure(
+ struct TWOmxNodeWrapper;
+ struct TWOmxBufferSource;
+ sp<GraphicBufferSource> mBase;
+ sp<IOmxBufferSource> mOmxBufferSource;
+
+ TWGraphicBufferSource(sp<GraphicBufferSource> const& base);
+ Return<Status> configure(
const sp<IOmxNode>& omxNode, Dataspace dataspace) override;
- Return<void> setSuspend(bool suspend, int64_t timeUs) override;
- Return<void> setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) override;
- Return<void> setMaxFps(float maxFps) override;
- Return<void> setTimeLapseConfig(
+ Return<Status> setSuspend(bool suspend, int64_t timeUs) override;
+ Return<Status> setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) override;
+ Return<Status> setMaxFps(float maxFps) override;
+ Return<Status> setTimeLapseConfig(
int64_t timePerFrameUs, int64_t timePerCaptureUs) override;
- Return<void> setStartTimeUs(int64_t startTimeUs) override;
- Return<void> setStopTimeUs(int64_t stopTimeUs) override;
- Return<void> setColorAspects(const ColorAspects& aspects) override;
- Return<void> setTimeOffsetUs(int64_t timeOffsetUs) override;
- Return<void> signalEndOfInputStream() override;
+ Return<Status> setStartTimeUs(int64_t startTimeUs) override;
+ Return<Status> setStopTimeUs(int64_t stopTimeUs) override;
+ Return<Status> setColorAspects(const ColorAspects& aspects) override;
+ Return<Status> setTimeOffsetUs(int64_t timeOffsetUs) override;
+ Return<Status> signalEndOfInputStream() override;
};
} // namespace implementation
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmx.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmx.cpp
deleted file mode 100644
index da1c23d..0000000
--- a/media/libstagefright/omx/hal/1.0/impl/WOmx.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "WOmx.h"
-#include "WOmxNode.h"
-#include "WOmxObserver.h"
-#include "WOmxBufferProducer.h"
-#include "WGraphicBufferSource.h"
-#include "Conversion.h"
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace omx {
-namespace V1_0 {
-namespace implementation {
-
-// LWOmx
-LWOmx::LWOmx(sp<IOmx> const& base) : mBase(base) {
-}
-
-status_t LWOmx::listNodes(List<IOMX::ComponentInfo>* list) {
- status_t fnStatus;
- status_t transStatus = toStatusT(mBase->listNodes(
- [&fnStatus, list](
- Status status,
- hidl_vec<IOmx::ComponentInfo> const& nodeList) {
- fnStatus = toStatusT(status);
- list->clear();
- for (size_t i = 0; i < nodeList.size(); ++i) {
- auto newInfo = list->insert(
- list->end(), IOMX::ComponentInfo());
- convertTo(&*newInfo, nodeList[i]);
- }
- }));
- return transStatus == NO_ERROR ? fnStatus : transStatus;
-}
-
-status_t LWOmx::allocateNode(
- char const* name,
- sp<IOMXObserver> const& observer,
- sp<IOMXNode>* omxNode) {
- status_t fnStatus;
- status_t transStatus = toStatusT(mBase->allocateNode(
- name, new TWOmxObserver(observer),
- [&fnStatus, omxNode](Status status, sp<IOmxNode> const& node) {
- fnStatus = toStatusT(status);
- *omxNode = new LWOmxNode(node);
- }));
- return transStatus == NO_ERROR ? fnStatus : transStatus;
-}
-
-status_t LWOmx::createInputSurface(
- sp<::android::IGraphicBufferProducer>* bufferProducer,
- sp<::android::IGraphicBufferSource>* bufferSource) {
- status_t fnStatus;
- status_t transStatus = toStatusT(mBase->createInputSurface(
- [&fnStatus, bufferProducer, bufferSource] (
- Status status,
- sp<IOmxBufferProducer> const& tProducer,
- sp<IGraphicBufferSource> const& tSource) {
- fnStatus = toStatusT(status);
- *bufferProducer = new LWOmxBufferProducer(tProducer);
- *bufferSource = new LWGraphicBufferSource(tSource);
- }));
- return transStatus == NO_ERROR ? fnStatus : transStatus;
-}
-
-// TWOmx
-TWOmx::TWOmx(sp<IOMX> const& base) : mBase(base) {
-}
-
-Return<void> TWOmx::listNodes(listNodes_cb _hidl_cb) {
- List<IOMX::ComponentInfo> lList;
- Status status = toStatus(mBase->listNodes(&lList));
-
- hidl_vec<IOmx::ComponentInfo> tList;
- tList.resize(lList.size());
- size_t i = 0;
- for (auto const& lInfo : lList) {
- convertTo(&(tList[i++]), lInfo);
- }
- _hidl_cb(status, tList);
- return Void();
-}
-
-Return<void> TWOmx::allocateNode(
- const hidl_string& name,
- const sp<IOmxObserver>& observer,
- allocateNode_cb _hidl_cb) {
- sp<IOMXNode> omxNode;
- Status status = toStatus(mBase->allocateNode(
- name, new LWOmxObserver(observer), &omxNode));
- _hidl_cb(status, new TWOmxNode(omxNode));
- return Void();
-}
-
-Return<void> TWOmx::createInputSurface(createInputSurface_cb _hidl_cb) {
- sp<::android::IGraphicBufferProducer> lProducer;
- sp<::android::IGraphicBufferSource> lSource;
- status_t status = mBase->createInputSurface(&lProducer, &lSource);
- _hidl_cb(toStatus(status),
- new TWOmxBufferProducer(lProducer),
- new TWGraphicBufferSource(lSource));
- return Void();
-}
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace omx
-} // namespace media
-} // namespace hardware
-} // namespace android
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmx.h b/media/libstagefright/omx/hal/1.0/impl/WOmx.h
deleted file mode 100644
index 3cb002e..0000000
--- a/media/libstagefright/omx/hal/1.0/impl/WOmx.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMX_H
-#define ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMX_H
-
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-
-#include "../../../../include/OMXNodeInstance.h"
-
-#include <android/hardware/media/omx/1.0/IOmx.h>
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace omx {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::media::omx::V1_0::IOmx;
-using ::android::hardware::media::omx::V1_0::IOmxNode;
-using ::android::hardware::media::omx::V1_0::IOmxObserver;
-using ::android::hardware::media::omx::V1_0::Status;
-using ::android::hidl::base::V1_0::IBase;
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-
-using ::android::List;
-using ::android::IOMX;
-using ::android::BnOMX;
-
-/**
- * Wrapper classes for conversion
- * ==============================
- *
- * Naming convention:
- * - LW = Legacy Wrapper --- It wraps a Treble object inside a legacy object.
- * - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
- */
-
-struct LWOmx : public BnOMX {
- sp<IOmx> mBase;
- LWOmx(sp<IOmx> const& base);
- status_t listNodes(List<IOMX::ComponentInfo>* list) override;
- status_t allocateNode(
- char const* name,
- sp<IOMXObserver> const& observer,
- sp<IOMXNode>* omxNode) override;
- status_t createInputSurface(
- sp<::android::IGraphicBufferProducer>* bufferProducer,
- sp<::android::IGraphicBufferSource>* bufferSource) override;
-};
-
-struct TWOmx : public IOmx {
- sp<IOMX> mBase;
- TWOmx(sp<IOMX> const& base);
- Return<void> listNodes(listNodes_cb _hidl_cb) override;
- Return<void> allocateNode(
- const hidl_string& name,
- const sp<IOmxObserver>& observer,
- allocateNode_cb _hidl_cb) override;
- Return<void> createInputSurface(createInputSurface_cb _hidl_cb) override;
-
-};
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace omx
-} // namespace media
-} // namespace hardware
-} // namespace android
-
-#endif // ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMX_H
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 5a1d6dc..88dabff 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -54,7 +54,7 @@
MTP_OPERATION_SEND_OBJECT,
// MTP_OPERATION_INITIATE_CAPTURE,
// MTP_OPERATION_FORMAT_STORE,
-// MTP_OPERATION_RESET_DEVICE,
+ MTP_OPERATION_RESET_DEVICE,
// MTP_OPERATION_SELF_TEST,
// MTP_OPERATION_SET_OBJECT_PROTECTION,
// MTP_OPERATION_POWER_DOWN,
@@ -362,6 +362,7 @@
case MTP_OPERATION_OPEN_SESSION:
response = doOpenSession();
break;
+ case MTP_OPERATION_RESET_DEVICE:
case MTP_OPERATION_CLOSE_SESSION:
response = doCloseSession();
break;
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 44fd512..4a279ea 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -563,6 +563,7 @@
virtual status_t getMmapPosition(struct audio_mmap_position *position);
virtual status_t start(const MmapStreamInterface::Client& client, audio_port_handle_t *handle);
virtual status_t stop(audio_port_handle_t handle);
+ virtual status_t standby();
private:
sp<MmapThread> mThread;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index b10e42c..993e76c 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -7434,7 +7434,7 @@
{
MmapThread *thread = mThread.get();
// clear our strong reference before disconnecting the thread: the last strong reference
- // will be removed when closeInput/closeOutput is executed upono call from audio policy manager
+ // will be removed when closeInput/closeOutput is executed upon call from audio policy manager
// and the thread removed from mMMapThreads list causing the thread destruction.
mThread.clear();
if (thread != nullptr) {
@@ -7476,6 +7476,14 @@
return mThread->stop(handle);
}
+status_t AudioFlinger::MmapThreadHandle::standby()
+{
+ if (mThread == 0) {
+ return NO_INIT;
+ }
+ return mThread->standby();
+}
+
AudioFlinger::MmapThread::MmapThread(
const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
@@ -7484,11 +7492,13 @@
: ThreadBase(audioFlinger, id, outDevice, inDevice, MMAP, systemReady),
mHalStream(stream), mHalDevice(hwDev->hwDevice()), mAudioHwDev(hwDev)
{
+ mStandby = true;
readHalParameters_l();
}
AudioFlinger::MmapThread::~MmapThread()
{
+ releaseWakeLock_l();
}
void AudioFlinger::MmapThread::onFirstRef()
@@ -7528,6 +7538,8 @@
if (mHalStream == 0) {
return NO_INIT;
}
+ mStandby = true;
+ acquireWakeLock();
return mHalStream->createMmapBuffer(minSizeFrames, info);
}
@@ -7542,7 +7554,7 @@
status_t AudioFlinger::MmapThread::start(const MmapStreamInterface::Client& client,
audio_port_handle_t *handle)
{
- ALOGV("%s clientUid %d", __FUNCTION__, client.clientUid);
+ ALOGV("%s clientUid %d mStandby %d", __FUNCTION__, client.clientUid, mStandby);
if (mHalStream == 0) {
return NO_INIT;
}
@@ -7556,6 +7568,7 @@
mHalStream->start();
portId = mPortId;
sessionId = mSessionId;
+ mStandby = false;
} else {
// for other tracks than first one, get a new port ID from APM.
sessionId = (audio_session_t)mAudioFlinger->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
@@ -7613,6 +7626,8 @@
} else {
AudioSystem::releaseInput(mId, sessionId);
}
+ } else {
+ mHalStream->stop();
}
return PERMISSION_DENIED;
}
@@ -7632,14 +7647,13 @@
broadcast_l();
- ALOGV("%s DONE handle %d", __FUNCTION__, portId);
+ ALOGV("%s DONE handle %d stream %p", __FUNCTION__, portId, mHalStream.get());
return NO_ERROR;
}
status_t AudioFlinger::MmapThread::stop(audio_port_handle_t handle)
{
-
ALOGV("%s handle %d", __FUNCTION__, handle);
if (mHalStream == 0) {
@@ -7685,6 +7699,22 @@
return NO_ERROR;
}
+status_t AudioFlinger::MmapThread::standby()
+{
+ ALOGV("%s", __FUNCTION__);
+
+ if (mHalStream == 0) {
+ return NO_INIT;
+ }
+ if (mActiveTracks.size() != 0) {
+ return INVALID_OPERATION;
+ }
+ mHalStream->standby();
+ mStandby = true;
+ releaseWakeLock();
+ return NO_ERROR;
+}
+
void AudioFlinger::MmapThread::readHalParameters_l()
{
@@ -7701,8 +7731,6 @@
bool AudioFlinger::MmapThread::threadLoop()
{
- acquireWakeLock();
-
checkSilentMode_l();
const String8 myName(String8::format("thread %p type %d TID %d", this, mType, gettid()));
@@ -7724,18 +7752,10 @@
break;
}
- bool wakelockReleased = false;
- if (mActiveTracks.size() == 0) {
- releaseWakeLock_l();
- wakelockReleased = true;
- }
// wait until we have something to do...
ALOGV("%s going to sleep", myName.string());
mWaitWorkCV.wait(mLock);
ALOGV("%s waking up", myName.string());
- if (wakelockReleased) {
- acquireWakeLock_l();
- }
checkSilentMode_l();
@@ -7768,8 +7788,6 @@
mStandby = true;
}
- releaseWakeLock();
-
ALOGV("Thread %p type %d exiting", this, mType);
return false;
}
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 0a17a8e..422eeb5 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1540,6 +1540,7 @@
status_t getMmapPosition(struct audio_mmap_position *position);
status_t start(const MmapStreamInterface::Client& client, audio_port_handle_t *handle);
status_t stop(audio_port_handle_t handle);
+ status_t standby();
// RefBase
virtual void onFirstRef();
@@ -1549,6 +1550,7 @@
virtual void threadLoop_exit();
virtual void threadLoop_standby();
+ virtual bool shouldStandby_l() { return false; }
virtual status_t initCheck() const { return (mHalStream == 0) ? NO_INIT : NO_ERROR; }
virtual size_t frameCount() const { return mFrameCount; }
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 79e7ff0..4428f75 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -321,7 +321,7 @@
return binder::Status::ok();
}
-binder::Status CameraDeviceClient::endConfigure(bool isConstrainedHighSpeed) {
+binder::Status CameraDeviceClient::endConfigure(int operatingMode) {
ALOGV("%s: ending configure (%d input stream, %zu output surfaces)",
__FUNCTION__, mInputStream.configured ? 1 : 0,
mStreamMap.size());
@@ -335,7 +335,16 @@
return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
}
+ if (operatingMode < 0) {
+ String8 msg = String8::format(
+ "Camera %s: Invalid operating mode %d requested", mCameraIdStr.string(), operatingMode);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+ msg.string());
+ }
+
// Sanitize the high speed session against necessary capability bit.
+ bool isConstrainedHighSpeed = (operatingMode == ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE);
if (isConstrainedHighSpeed) {
CameraMetadata staticInfo = mDevice->info();
camera_metadata_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
@@ -357,7 +366,7 @@
}
}
- status_t err = mDevice->configureStreams(isConstrainedHighSpeed);
+ status_t err = mDevice->configureStreams(operatingMode);
if (err == BAD_VALUE) {
String8 msg = String8::format("Camera %s: Unsupported set of inputs/outputs provided",
mCameraIdStr.string());
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 012beb4..2a95c88 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -70,70 +70,70 @@
const hardware::camera2::CaptureRequest& request,
bool streaming = false,
/*out*/
- hardware::camera2::utils::SubmitInfo *submitInfo = nullptr);
+ hardware::camera2::utils::SubmitInfo *submitInfo = nullptr) override;
// List of requests are copied.
virtual binder::Status submitRequestList(
const std::vector<hardware::camera2::CaptureRequest>& requests,
bool streaming = false,
/*out*/
- hardware::camera2::utils::SubmitInfo *submitInfo = nullptr);
+ hardware::camera2::utils::SubmitInfo *submitInfo = nullptr) override;
virtual binder::Status cancelRequest(int requestId,
/*out*/
- int64_t* lastFrameNumber = NULL);
+ int64_t* lastFrameNumber = NULL) override;
- virtual binder::Status beginConfigure();
+ virtual binder::Status beginConfigure() override;
- virtual binder::Status endConfigure(bool isConstrainedHighSpeed = false);
+ virtual binder::Status endConfigure(int operatingMode) override;
// Returns -EBUSY if device is not idle
- virtual binder::Status deleteStream(int streamId);
+ virtual binder::Status deleteStream(int streamId) override;
virtual binder::Status createStream(
const hardware::camera2::params::OutputConfiguration &outputConfiguration,
/*out*/
- int32_t* newStreamId = NULL);
+ int32_t* newStreamId = NULL) override;
// Create an input stream of width, height, and format.
virtual binder::Status createInputStream(int width, int height, int format,
/*out*/
- int32_t* newStreamId = NULL);
+ int32_t* newStreamId = NULL) override;
// Get the buffer producer of the input stream
virtual binder::Status getInputSurface(
/*out*/
- view::Surface *inputSurface);
+ view::Surface *inputSurface) override;
// Create a request object from a template.
virtual binder::Status createDefaultRequest(int templateId,
/*out*/
- hardware::camera2::impl::CameraMetadataNative* request);
+ hardware::camera2::impl::CameraMetadataNative* request) override;
// Get the static metadata for the camera
// -- Caller owns the newly allocated metadata
virtual binder::Status getCameraInfo(
/*out*/
- hardware::camera2::impl::CameraMetadataNative* cameraCharacteristics);
+ hardware::camera2::impl::CameraMetadataNative* cameraCharacteristics) override;
// Wait until all the submitted requests have finished processing
- virtual binder::Status waitUntilIdle();
+ virtual binder::Status waitUntilIdle() override;
// Flush all active and pending requests as fast as possible
virtual binder::Status flush(
/*out*/
- int64_t* lastFrameNumber = NULL);
+ int64_t* lastFrameNumber = NULL) override;
// Prepare stream by preallocating its buffers
- virtual binder::Status prepare(int32_t streamId);
+ virtual binder::Status prepare(int32_t streamId) override;
// Tear down stream resources by freeing its unused buffers
- virtual binder::Status tearDown(int32_t streamId);
+ virtual binder::Status tearDown(int32_t streamId) override;
// Prepare stream by preallocating up to maxCount of its buffers
- virtual binder::Status prepare2(int32_t maxCount, int32_t streamId);
+ virtual binder::Status prepare2(int32_t maxCount, int32_t streamId) override;
// Finalize the output configurations with surfaces not added before.
virtual binder::Status finalizeOutputConfigurations(int32_t streamId,
- const hardware::camera2::params::OutputConfiguration &outputConfiguration);
+ const hardware::camera2::params::OutputConfiguration &outputConfiguration) override;
/**
* Interface used by CameraService
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 98a3fcc..f9b062a 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -184,7 +184,7 @@
* - BAD_VALUE if the set of streams was invalid (e.g. fmts or sizes)
* - INVALID_OPERATION if the device was in the wrong state
*/
- virtual status_t configureStreams(bool isConstrainedHighSpeed = false) = 0;
+ virtual status_t configureStreams(int operatingMode = 0) = 0;
// get the buffer producer of the input stream
virtual status_t getInputBufferProducer(
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
index d45891f..d93b331 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
@@ -19,7 +19,6 @@
#define ATRACE_TAG ATRACE_TAG_CAMERA
#include <gui/ISurfaceComposer.h>
-#include <gui/IGraphicBufferAlloc.h>
#include <private/gui/ComposerService.h>
#include <utils/Log.h>
#include <utils/Trace.h>
@@ -30,15 +29,7 @@
namespace camera3 {
-Camera3BufferManager::Camera3BufferManager(const sp<IGraphicBufferAlloc>& allocator) :
- mAllocator(allocator) {
- if (allocator == NULL) {
- sp<ISurfaceComposer> composer(ComposerService::getComposerService());
- mAllocator = composer->createGraphicBufferAlloc();
- if (mAllocator == NULL) {
- ALOGE("createGraphicBufferAlloc failed");
- }
- }
+Camera3BufferManager::Camera3BufferManager() {
}
Camera3BufferManager::~Camera3BufferManager() {
@@ -79,10 +70,6 @@
}
Mutex::Autolock l(mLock);
- if (mAllocator == NULL) {
- ALOGE("%s: allocator is NULL, buffer manager is bad state.", __FUNCTION__);
- return INVALID_OPERATION;
- }
// Check if this stream was registered with different stream set ID, if so, error out.
for (size_t i = 0; i < mStreamSetMap.size(); i++) {
@@ -132,10 +119,6 @@
Mutex::Autolock l(mLock);
ALOGV("%s: unregister stream %d with stream set %d", __FUNCTION__,
streamId, streamSetId);
- if (mAllocator == NULL) {
- ALOGE("%s: allocator is NULL, buffer manager is bad state.", __FUNCTION__);
- return INVALID_OPERATION;
- }
if (!checkIfStreamRegisteredLocked(streamId, streamSetId)){
ALOGE("%s: stream %d with set id %d wasn't properly registered to this buffer manager!",
@@ -182,10 +165,6 @@
Mutex::Autolock l(mLock);
ALOGV("%s: get buffer for stream %d with stream set %d", __FUNCTION__,
streamId, streamSetId);
- if (mAllocator == NULL) {
- ALOGE("%s: allocator is NULL, buffer manager is bad state.", __FUNCTION__);
- return INVALID_OPERATION;
- }
if (!checkIfStreamRegisteredLocked(streamId, streamSetId)) {
ALOGE("%s: stream %d is not registered with stream set %d yet!!!",
@@ -219,15 +198,18 @@
// Allocate one if there is no free buffer available.
if (buffer.graphicBuffer == nullptr) {
const StreamInfo& info = streamSet.streamInfoMap.valueFor(streamId);
- status_t res = OK;
buffer.fenceFd = -1;
- buffer.graphicBuffer = mAllocator->createGraphicBuffer(
- info.width, info.height, info.format, 1 /* layerCount */,
- info.combinedUsage, &res);
+
+ buffer.graphicBuffer = new GraphicBuffer(
+ info.width, info.height, PixelFormat(info.format), info.combinedUsage,
+ std::string("Camera3BufferManager pid [") +
+ std::to_string(getpid()) + "]");
+ status_t res = buffer.graphicBuffer->initCheck();
+
ALOGV("%s: allocating a new graphic buffer (%dx%d, format 0x%x) %p with handle %p",
__FUNCTION__, info.width, info.height, info.format,
buffer.graphicBuffer.get(), buffer.graphicBuffer->handle);
- if (res != OK) {
+ if (res < 0) {
ALOGE("%s: graphic buffer allocation failed: (error %d %s) ",
__FUNCTION__, res, strerror(-res));
return res;
@@ -331,10 +313,6 @@
Mutex::Autolock l(mLock);
ALOGV("Stream %d set %d: Buffer released", streamId, streamSetId);
- if (mAllocator == NULL) {
- ALOGE("%s: allocator is NULL, buffer manager is bad state.", __FUNCTION__);
- return INVALID_OPERATION;
- }
if (!checkIfStreamRegisteredLocked(streamId, streamSetId)){
ALOGV("%s: signaling buffer release for an already unregistered stream "
@@ -363,10 +341,6 @@
Mutex::Autolock l(mLock);
ALOGV_IF(buffer != 0, "%s: return buffer (%p) with handle (%p) for stream %d and stream set %d",
__FUNCTION__, buffer.get(), buffer->handle, streamId, streamSetId);
- if (mAllocator == NULL) {
- ALOGE("%s: allocator is NULL, buffer manager is bad state.", __FUNCTION__);
- return INVALID_OPERATION;
- }
if (!checkIfStreamRegisteredLocked(streamId, streamSetId)){
ALOGV("%s: returning buffer for an already unregistered stream (stream %d with set id %d),"
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.h b/services/camera/libcameraservice/device3/Camera3BufferManager.h
index f44c4a3..d1d7a6f 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.h
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.h
@@ -26,8 +26,6 @@
namespace android {
-class IGraphicBufferAlloc;
-
namespace camera3 {
struct StreamInfo;
@@ -46,7 +44,7 @@
*/
class Camera3BufferManager: public virtual RefBase {
public:
- explicit Camera3BufferManager(const sp<IGraphicBufferAlloc>& allocator = NULL);
+ explicit Camera3BufferManager();
virtual ~Camera3BufferManager();
@@ -188,12 +186,6 @@
static const size_t kMaxBufferCount = BufferQueueDefs::NUM_BUFFER_SLOTS;
- /**
- * mAllocator is the connection to SurfaceFlinger that is used to allocate new GraphicBuffer
- * objects.
- */
- sp<IGraphicBufferAlloc> mAllocator;
-
struct GraphicBufferEntry {
sp<GraphicBuffer> graphicBuffer;
int fenceFd;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index f20556d..4d5abed 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -63,6 +63,7 @@
Camera3Device::Camera3Device(const String8 &id):
mId(id),
+ mOperatingMode(NO_MODE),
mIsConstrainedHighSpeedConfiguration(false),
mStatus(STATUS_UNINITIALIZED),
mStatusWaiters(0),
@@ -514,19 +515,25 @@
return StreamRotation::ROTATION_0;
}
-StreamConfigurationMode Camera3Device::mapToStreamConfigurationMode(
- camera3_stream_configuration_mode_t operationMode) {
- switch(operationMode) {
- case CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE:
- return StreamConfigurationMode::NORMAL_MODE;
- case CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
- return StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
- case CAMERA3_VENDOR_STREAM_CONFIGURATION_MODE_START:
- // Needs to be mapped by vendor extensions
- break;
+status_t Camera3Device::mapToStreamConfigurationMode(
+ camera3_stream_configuration_mode_t operationMode, StreamConfigurationMode *mode) {
+ if (mode == nullptr) return BAD_VALUE;
+ if (operationMode < CAMERA3_VENDOR_STREAM_CONFIGURATION_MODE_START) {
+ switch(operationMode) {
+ case CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE:
+ *mode = StreamConfigurationMode::NORMAL_MODE;
+ break;
+ case CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
+ *mode = StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
+ break;
+ default:
+ ALOGE("%s: Unknown stream configuration mode %d", __FUNCTION__, operationMode);
+ return BAD_VALUE;
+ }
+ } else {
+ *mode = static_cast<StreamConfigurationMode>(operationMode);
}
- ALOGE("%s: Unknown stream configuration mode %d", __FUNCTION__, operationMode);
- return StreamConfigurationMode::NORMAL_MODE;
+ return OK;
}
camera3_buffer_status_t Camera3Device::mapHidlBufferStatus(BufferStatus status) {
@@ -677,8 +684,12 @@
lines.appendFormat(" Error cause: %s\n", mErrorCause.string());
}
lines.appendFormat(" Stream configuration:\n");
- lines.appendFormat(" Operation mode: %s \n", mIsConstrainedHighSpeedConfiguration ?
- "CONSTRAINED HIGH SPEED VIDEO" : "NORMAL");
+ const char *mode =
+ mOperatingMode == static_cast<int>(StreamConfigurationMode::NORMAL_MODE) ? "NORMAL" :
+ mOperatingMode == static_cast<int>(
+ StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE) ? "CONSTRAINED_HIGH_SPEED" :
+ "CUSTOM";
+ lines.appendFormat(" Operation mode: %s (%d) \n", mode, mOperatingMode);
if (mInputStream != NULL) {
write(fd, lines.string(), lines.size());
@@ -1093,7 +1104,9 @@
status_t res;
if (mStatus == STATUS_UNCONFIGURED || mNeedConfig) {
- res = configureStreamsLocked();
+ // This point should only be reached via API1 (API2 must explicitly call configureStreams)
+ // so unilaterally select normal operating mode.
+ res = configureStreamsLocked(CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE);
// Stream configuration failed. Client might try other configuraitons.
if (res != OK) {
CLOGE("Can't set up streams: %s (%d)", strerror(-res), res);
@@ -1195,7 +1208,8 @@
// Continue captures if active at start
if (wasActive) {
ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
- res = configureStreamsLocked();
+ // Reuse current operating mode for new stream config
+ res = configureStreamsLocked(mOperatingMode);
if (res != OK) {
ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
__FUNCTION__, mNextStreamId, strerror(-res), res);
@@ -1357,7 +1371,8 @@
// Continue captures if active at start
if (wasActive) {
ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
- res = configureStreamsLocked();
+ // Reuse current operating mode for new stream config
+ res = configureStreamsLocked(mOperatingMode);
if (res != OK) {
CLOGE("Can't reconfigure device for new stream %d: %s (%d)",
mNextStreamId, strerror(-res), res);
@@ -1501,19 +1516,14 @@
return INVALID_OPERATION;
}
-status_t Camera3Device::configureStreams(bool isConstrainedHighSpeed) {
+status_t Camera3Device::configureStreams(int operatingMode) {
ATRACE_CALL();
ALOGV("%s: E", __FUNCTION__);
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
- if (mIsConstrainedHighSpeedConfiguration != isConstrainedHighSpeed) {
- mNeedConfig = true;
- mIsConstrainedHighSpeedConfiguration = isConstrainedHighSpeed;
- }
-
- return configureStreamsLocked();
+ return configureStreamsLocked(operatingMode);
}
status_t Camera3Device::getInputBufferProducer(
@@ -2161,7 +2171,7 @@
mNeedConfig = true;
}
-status_t Camera3Device::configureStreamsLocked() {
+status_t Camera3Device::configureStreamsLocked(int operatingMode) {
ATRACE_CALL();
status_t res;
@@ -2170,6 +2180,21 @@
return INVALID_OPERATION;
}
+ if (operatingMode < 0) {
+ CLOGE("Invalid operating mode: %d", operatingMode);
+ return BAD_VALUE;
+ }
+
+ bool isConstrainedHighSpeed =
+ static_cast<int>(StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE) ==
+ operatingMode;
+
+ if (mOperatingMode != operatingMode) {
+ mNeedConfig = true;
+ mIsConstrainedHighSpeedConfiguration = isConstrainedHighSpeed;
+ mOperatingMode = operatingMode;
+ }
+
if (!mNeedConfig) {
ALOGV("%s: Skipping config, no stream changes", __FUNCTION__);
return OK;
@@ -2188,9 +2213,7 @@
ALOGV("%s: Camera %s: Starting stream configuration", __FUNCTION__, mId.string());
camera3_stream_configuration config;
- config.operation_mode = mIsConstrainedHighSpeedConfiguration ?
- CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE :
- CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE;
+ config.operation_mode = mOperatingMode;
config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
Vector<camera3_stream_t*> streams;
@@ -3149,8 +3172,12 @@
}
}
- requestedConfiguration.operationMode = mapToStreamConfigurationMode(
- (camera3_stream_configuration_mode_t) config->operation_mode);
+ res = mapToStreamConfigurationMode(
+ (camera3_stream_configuration_mode_t) config->operation_mode,
+ /*out*/ &requestedConfiguration.operationMode);
+ if (res != OK) {
+ return res;
+ }
// Invoke configureStreams
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index e19b62e..998cc0b 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -135,7 +135,9 @@
status_t deleteStream(int id) override;
status_t deleteReprocessStream(int id) override;
- status_t configureStreams(bool isConstraiedHighSpeed = false) override;
+ status_t configureStreams(int operatingMode =
+ static_cast<int>(hardware::camera::device::V3_2::StreamConfigurationMode::NORMAL_MODE))
+ override;
status_t getInputBufferProducer(
sp<IGraphicBufferProducer> *producer) override;
@@ -212,6 +214,11 @@
// Camera device ID
const String8 mId;
+ // Current stream configuration mode;
+ int mOperatingMode;
+ // Constant to use for no set operating mode
+ static const int NO_MODE = -1;
+
// Flag indicating is the current active stream configuration is constrained high speed.
bool mIsConstrainedHighSpeedConfiguration;
@@ -508,7 +515,7 @@
* Take the currently-defined set of streams and configure the HAL to use
* them. This is a long-running operation (may be several hundered ms).
*/
- status_t configureStreamsLocked();
+ status_t configureStreamsLocked(int operatingMode);
/**
* Cancel stream configuration that did not finish successfully.
@@ -574,8 +581,9 @@
static hardware::camera::device::V3_2::ConsumerUsageFlags mapToConsumerUsage(uint32_t usage);
static hardware::camera::device::V3_2::StreamRotation mapToStreamRotation(
camera3_stream_rotation_t rotation);
- static hardware::camera::device::V3_2::StreamConfigurationMode mapToStreamConfigurationMode(
- camera3_stream_configuration_mode_t operationMode);
+ // Returns a negative error code if the passed-in operation mode is not valid.
+ static status_t mapToStreamConfigurationMode(camera3_stream_configuration_mode_t operationMode,
+ /*out*/ hardware::camera::device::V3_2::StreamConfigurationMode *mode);
static camera3_buffer_status_t mapHidlBufferStatus(hardware::camera::device::V3_2::BufferStatus status);
static int mapToFrameworkFormat(hardware::graphics::common::V1_0::PixelFormat pixelFormat);
static uint32_t mapConsumerToFrameworkUsage(