Loading include/media/IOMX.h +1 −0 Original line number Diff line number Diff line Loading @@ -186,6 +186,7 @@ public: INTERNAL_OPTION_MAX_FPS, // data is float INTERNAL_OPTION_START_TIME, // data is an int64_t INTERNAL_OPTION_TIME_LAPSE, // data is an int64_t[2] INTERNAL_OPTION_COLOR_ASPECTS, // data is ColorAspects }; virtual status_t setInternalOption( node_id node, Loading media/libstagefright/omx/GraphicBufferSource.cpp +11 −4 Original line number Diff line number Diff line Loading @@ -190,6 +190,8 @@ GraphicBufferSource::GraphicBufferSource( return; } memset(&mColorAspects, 0, sizeof(mColorAspects)); CHECK(mInitCheck == NO_ERROR); } Loading Loading @@ -981,19 +983,24 @@ void GraphicBufferSource::setSkipFramesBeforeUs(int64_t skipFramesBeforeUs) { (skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll; } status_t GraphicBufferSource::setTimeLapseUs(int64_t* data) { status_t GraphicBufferSource::setTimeLapseConfig(const TimeLapseConfig &config) { Mutex::Autolock autoLock(mMutex); if (mExecuting || data[0] <= 0ll || data[1] <= 0ll) { if (mExecuting || config.mTimePerFrameUs <= 0ll || config.mTimePerCaptureUs <= 0ll) { return INVALID_OPERATION; } mTimePerFrameUs = data[0]; mTimePerCaptureUs = data[1]; mTimePerFrameUs = config.mTimePerFrameUs; mTimePerCaptureUs = config.mTimePerCaptureUs; return OK; } void GraphicBufferSource::setColorAspects(const ColorAspects &aspects) { Mutex::Autolock autoLock(mMutex); mColorAspects = aspects; } void GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatRepeatLastFrame: Loading media/libstagefright/omx/GraphicBufferSource.h +11 −3 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <utils/RefBase.h> #include <OMX_Core.h> #include <VideoAPI.h> #include "../include/OMXNodeInstance.h" #include <media/stagefright/foundation/ABase.h> #include <media/stagefright/foundation/AHandlerReflector.h> Loading Loading @@ -133,17 +134,23 @@ public: // When set, the max frame rate fed to the encoder will be capped at maxFps. status_t setMaxFps(float maxFps); struct TimeLapseConfig { int64_t mTimePerFrameUs; // the time (us) between two frames for playback int64_t mTimePerCaptureUs; // the time (us) between two frames for capture }; // Sets the time lapse (or slow motion) parameters. // data[0] is the time (us) between two frames for playback // data[1] is the time (us) between two frames for capture // When set, the sample's timestamp will be modified to playback framerate, // and capture timestamp will be modified to capture rate. status_t setTimeLapseUs(int64_t* data); status_t setTimeLapseConfig(const TimeLapseConfig &config); // Sets the start time us (in system time), samples before which should // be dropped and not submitted to encoder void setSkipFramesBeforeUs(int64_t startTimeUs); // Sets the desired color aspects, e.g. to be used when producer does not specify a dataspace. void setColorAspects(const ColorAspects &aspects); protected: // BufferQueue::ConsumerListener interface, called when a new frame of // data is available. If we're executing and a codec buffer is Loading Loading @@ -327,6 +334,7 @@ private: int64_t mPrevFrameUs; MetadataBufferType mMetadataBufferType; ColorAspects mColorAspects; void onMessageReceived(const sp<AMessage> &msg); Loading media/libstagefright/omx/OMXNodeInstance.cpp +36 −20 Original line number Diff line number Diff line Loading @@ -1362,6 +1362,16 @@ inline static const char *asString(IOMX::InternalOptionType i, const char *def = } } template<typename T> static bool getInternalOption( const void *data, size_t size, T *out) { if (size != sizeof(T)) { return false; } *out = *(T*)data; return true; } status_t OMXNodeInstance::setInternalOption( OMX_U32 portIndex, IOMX::InternalOptionType type, Loading @@ -1376,6 +1386,7 @@ status_t OMXNodeInstance::setInternalOption( case IOMX::INTERNAL_OPTION_MAX_FPS: case IOMX::INTERNAL_OPTION_START_TIME: case IOMX::INTERNAL_OPTION_TIME_LAPSE: case IOMX::INTERNAL_OPTION_COLOR_ASPECTS: { const sp<GraphicBufferSource> &bufferSource = getGraphicBufferSource(); Loading @@ -1386,58 +1397,63 @@ status_t OMXNodeInstance::setInternalOption( } if (type == IOMX::INTERNAL_OPTION_SUSPEND) { if (size != sizeof(bool)) { bool suspend; if (!getInternalOption(data, size, &suspend)) { return INVALID_OPERATION; } bool suspend = *(bool *)data; CLOG_CONFIG(setInternalOption, "suspend=%d", suspend); bufferSource->suspend(suspend); } else if (type == IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY){ if (size != sizeof(int64_t)) { } else if (type == IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY) { int64_t delayUs; if (!getInternalOption(data, size, &delayUs)) { return INVALID_OPERATION; } int64_t delayUs = *(int64_t *)data; CLOG_CONFIG(setInternalOption, "delayUs=%lld", (long long)delayUs); return bufferSource->setRepeatPreviousFrameDelayUs(delayUs); } else if (type == IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP){ if (size != sizeof(int64_t)) { } else if (type == IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP) { int64_t maxGapUs; if (!getInternalOption(data, size, &maxGapUs)) { return INVALID_OPERATION; } int64_t maxGapUs = *(int64_t *)data; CLOG_CONFIG(setInternalOption, "gapUs=%lld", (long long)maxGapUs); return bufferSource->setMaxTimestampGapUs(maxGapUs); } else if (type == IOMX::INTERNAL_OPTION_MAX_FPS) { if (size != sizeof(float)) { float maxFps; if (!getInternalOption(data, size, &maxFps)) { return INVALID_OPERATION; } float maxFps = *(float *)data; CLOG_CONFIG(setInternalOption, "maxFps=%f", maxFps); return bufferSource->setMaxFps(maxFps); } else if (type == IOMX::INTERNAL_OPTION_START_TIME) { if (size != sizeof(int64_t)) { int64_t skipFramesBeforeUs; if (!getInternalOption(data, size, &skipFramesBeforeUs)) { return INVALID_OPERATION; } int64_t skipFramesBeforeUs = *(int64_t *)data; CLOG_CONFIG(setInternalOption, "beforeUs=%lld", (long long)skipFramesBeforeUs); bufferSource->setSkipFramesBeforeUs(skipFramesBeforeUs); } else { // IOMX::INTERNAL_OPTION_TIME_LAPSE if (size != sizeof(int64_t) * 2) { } else if (type == IOMX::INTERNAL_OPTION_TIME_LAPSE) { GraphicBufferSource::TimeLapseConfig config; if (!getInternalOption(data, size, &config)) { return INVALID_OPERATION; } int64_t timePerFrameUs = ((int64_t *)data)[0]; int64_t timePerCaptureUs = ((int64_t *)data)[1]; CLOG_CONFIG(setInternalOption, "perFrameUs=%lld perCaptureUs=%lld", (long long)timePerFrameUs, (long long)timePerCaptureUs); (long long)config.mTimePerFrameUs, (long long)config.mTimePerCaptureUs); return bufferSource->setTimeLapseConfig(config); } else if (type == IOMX::INTERNAL_OPTION_COLOR_ASPECTS) { ColorAspects aspects; if (!getInternalOption(data, size, &aspects)) { return INVALID_OPERATION; } bufferSource->setTimeLapseUs((int64_t *)data); CLOG_CONFIG(setInternalOption, "setting color aspects"); bufferSource->setColorAspects(aspects); } return OK; Loading Loading
include/media/IOMX.h +1 −0 Original line number Diff line number Diff line Loading @@ -186,6 +186,7 @@ public: INTERNAL_OPTION_MAX_FPS, // data is float INTERNAL_OPTION_START_TIME, // data is an int64_t INTERNAL_OPTION_TIME_LAPSE, // data is an int64_t[2] INTERNAL_OPTION_COLOR_ASPECTS, // data is ColorAspects }; virtual status_t setInternalOption( node_id node, Loading
media/libstagefright/omx/GraphicBufferSource.cpp +11 −4 Original line number Diff line number Diff line Loading @@ -190,6 +190,8 @@ GraphicBufferSource::GraphicBufferSource( return; } memset(&mColorAspects, 0, sizeof(mColorAspects)); CHECK(mInitCheck == NO_ERROR); } Loading Loading @@ -981,19 +983,24 @@ void GraphicBufferSource::setSkipFramesBeforeUs(int64_t skipFramesBeforeUs) { (skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll; } status_t GraphicBufferSource::setTimeLapseUs(int64_t* data) { status_t GraphicBufferSource::setTimeLapseConfig(const TimeLapseConfig &config) { Mutex::Autolock autoLock(mMutex); if (mExecuting || data[0] <= 0ll || data[1] <= 0ll) { if (mExecuting || config.mTimePerFrameUs <= 0ll || config.mTimePerCaptureUs <= 0ll) { return INVALID_OPERATION; } mTimePerFrameUs = data[0]; mTimePerCaptureUs = data[1]; mTimePerFrameUs = config.mTimePerFrameUs; mTimePerCaptureUs = config.mTimePerCaptureUs; return OK; } void GraphicBufferSource::setColorAspects(const ColorAspects &aspects) { Mutex::Autolock autoLock(mMutex); mColorAspects = aspects; } void GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatRepeatLastFrame: Loading
media/libstagefright/omx/GraphicBufferSource.h +11 −3 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <utils/RefBase.h> #include <OMX_Core.h> #include <VideoAPI.h> #include "../include/OMXNodeInstance.h" #include <media/stagefright/foundation/ABase.h> #include <media/stagefright/foundation/AHandlerReflector.h> Loading Loading @@ -133,17 +134,23 @@ public: // When set, the max frame rate fed to the encoder will be capped at maxFps. status_t setMaxFps(float maxFps); struct TimeLapseConfig { int64_t mTimePerFrameUs; // the time (us) between two frames for playback int64_t mTimePerCaptureUs; // the time (us) between two frames for capture }; // Sets the time lapse (or slow motion) parameters. // data[0] is the time (us) between two frames for playback // data[1] is the time (us) between two frames for capture // When set, the sample's timestamp will be modified to playback framerate, // and capture timestamp will be modified to capture rate. status_t setTimeLapseUs(int64_t* data); status_t setTimeLapseConfig(const TimeLapseConfig &config); // Sets the start time us (in system time), samples before which should // be dropped and not submitted to encoder void setSkipFramesBeforeUs(int64_t startTimeUs); // Sets the desired color aspects, e.g. to be used when producer does not specify a dataspace. void setColorAspects(const ColorAspects &aspects); protected: // BufferQueue::ConsumerListener interface, called when a new frame of // data is available. If we're executing and a codec buffer is Loading Loading @@ -327,6 +334,7 @@ private: int64_t mPrevFrameUs; MetadataBufferType mMetadataBufferType; ColorAspects mColorAspects; void onMessageReceived(const sp<AMessage> &msg); Loading
media/libstagefright/omx/OMXNodeInstance.cpp +36 −20 Original line number Diff line number Diff line Loading @@ -1362,6 +1362,16 @@ inline static const char *asString(IOMX::InternalOptionType i, const char *def = } } template<typename T> static bool getInternalOption( const void *data, size_t size, T *out) { if (size != sizeof(T)) { return false; } *out = *(T*)data; return true; } status_t OMXNodeInstance::setInternalOption( OMX_U32 portIndex, IOMX::InternalOptionType type, Loading @@ -1376,6 +1386,7 @@ status_t OMXNodeInstance::setInternalOption( case IOMX::INTERNAL_OPTION_MAX_FPS: case IOMX::INTERNAL_OPTION_START_TIME: case IOMX::INTERNAL_OPTION_TIME_LAPSE: case IOMX::INTERNAL_OPTION_COLOR_ASPECTS: { const sp<GraphicBufferSource> &bufferSource = getGraphicBufferSource(); Loading @@ -1386,58 +1397,63 @@ status_t OMXNodeInstance::setInternalOption( } if (type == IOMX::INTERNAL_OPTION_SUSPEND) { if (size != sizeof(bool)) { bool suspend; if (!getInternalOption(data, size, &suspend)) { return INVALID_OPERATION; } bool suspend = *(bool *)data; CLOG_CONFIG(setInternalOption, "suspend=%d", suspend); bufferSource->suspend(suspend); } else if (type == IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY){ if (size != sizeof(int64_t)) { } else if (type == IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY) { int64_t delayUs; if (!getInternalOption(data, size, &delayUs)) { return INVALID_OPERATION; } int64_t delayUs = *(int64_t *)data; CLOG_CONFIG(setInternalOption, "delayUs=%lld", (long long)delayUs); return bufferSource->setRepeatPreviousFrameDelayUs(delayUs); } else if (type == IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP){ if (size != sizeof(int64_t)) { } else if (type == IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP) { int64_t maxGapUs; if (!getInternalOption(data, size, &maxGapUs)) { return INVALID_OPERATION; } int64_t maxGapUs = *(int64_t *)data; CLOG_CONFIG(setInternalOption, "gapUs=%lld", (long long)maxGapUs); return bufferSource->setMaxTimestampGapUs(maxGapUs); } else if (type == IOMX::INTERNAL_OPTION_MAX_FPS) { if (size != sizeof(float)) { float maxFps; if (!getInternalOption(data, size, &maxFps)) { return INVALID_OPERATION; } float maxFps = *(float *)data; CLOG_CONFIG(setInternalOption, "maxFps=%f", maxFps); return bufferSource->setMaxFps(maxFps); } else if (type == IOMX::INTERNAL_OPTION_START_TIME) { if (size != sizeof(int64_t)) { int64_t skipFramesBeforeUs; if (!getInternalOption(data, size, &skipFramesBeforeUs)) { return INVALID_OPERATION; } int64_t skipFramesBeforeUs = *(int64_t *)data; CLOG_CONFIG(setInternalOption, "beforeUs=%lld", (long long)skipFramesBeforeUs); bufferSource->setSkipFramesBeforeUs(skipFramesBeforeUs); } else { // IOMX::INTERNAL_OPTION_TIME_LAPSE if (size != sizeof(int64_t) * 2) { } else if (type == IOMX::INTERNAL_OPTION_TIME_LAPSE) { GraphicBufferSource::TimeLapseConfig config; if (!getInternalOption(data, size, &config)) { return INVALID_OPERATION; } int64_t timePerFrameUs = ((int64_t *)data)[0]; int64_t timePerCaptureUs = ((int64_t *)data)[1]; CLOG_CONFIG(setInternalOption, "perFrameUs=%lld perCaptureUs=%lld", (long long)timePerFrameUs, (long long)timePerCaptureUs); (long long)config.mTimePerFrameUs, (long long)config.mTimePerCaptureUs); return bufferSource->setTimeLapseConfig(config); } else if (type == IOMX::INTERNAL_OPTION_COLOR_ASPECTS) { ColorAspects aspects; if (!getInternalOption(data, size, &aspects)) { return INVALID_OPERATION; } bufferSource->setTimeLapseUs((int64_t *)data); CLOG_CONFIG(setInternalOption, "setting color aspects"); bufferSource->setColorAspects(aspects); } return OK; Loading