summaryrefslogtreecommitdiffstats
path: root/media/libavextensions
diff options
context:
space:
mode:
authorSteve Kondik <steve@cyngn.com>2016-01-05 15:21:14 -0800
committerSteve Kondik <steve@cyngn.com>2016-01-05 15:22:11 -0800
commitde1e368d8ac5891e03e664a0ea385b896b48db0b (patch)
tree12b15ff95a32ca0a55d4fa9f94dbba8c886c09d8 /media/libavextensions
parent72f2347c4eb4aa50503cd990d1ab5c0f8f5bbb61 (diff)
downloadframeworks_av-de1e368d8ac5891e03e664a0ea385b896b48db0b.zip
frameworks_av-de1e368d8ac5891e03e664a0ea385b896b48db0b.tar.gz
frameworks_av-de1e368d8ac5891e03e664a0ea385b896b48db0b.tar.bz2
stagefright: Forward-port HFR and HSR support
* CAF commit bd42a7ac3a60c0d8a079b4567484c9b006bac8ad upstream Change-Id: I457ccab603647f3139ea2199a544f64ac3d1a214
Diffstat (limited to 'media/libavextensions')
-rw-r--r--media/libavextensions/stagefright/AVExtensions.h58
-rw-r--r--media/libavextensions/stagefright/AVUtils.cpp125
2 files changed, 181 insertions, 2 deletions
diff --git a/media/libavextensions/stagefright/AVExtensions.h b/media/libavextensions/stagefright/AVExtensions.h
index f14d217..968eb6d 100644
--- a/media/libavextensions/stagefright/AVExtensions.h
+++ b/media/libavextensions/stagefright/AVExtensions.h
@@ -153,7 +153,7 @@ struct AVUtils {
uint64_t /*eAacProfile*/);
virtual void extractCustomCameraKeys(
- const CameraParameters& /*params*/, sp<MetaData> &/*meta*/) {}
+ const CameraParameters& /*params*/, sp<MetaData> &/*meta*/);
virtual void printFileName(int /*fd*/) {}
virtual void addDecodingTimesFromBatch(MediaBuffer * /*buf*/,
List<int64_t> &/*decodeTimeQueue*/) {}
@@ -226,12 +226,66 @@ struct AVUtils {
int nPFrames, int nBFrames, const sp<IOMX> OMXhandle,
IOMX::node_id nodeID);
+ /*
+ * This class is a placeholder for the set of methods used
+ * to enable HFR (High Frame Rate) Recording
+ *
+ * HFR is a slow-motion recording feature where framerate
+ * is increased at capture, but file is composed to play
+ * back at normal rate, giving a net result of slow-motion.
+ * If HFR factor = N
+ * framerate (at capture and encoder) = N * actual value
+ * bitrate = N * actual value
+ * (as the encoder still gets actual timestamps)
+ * timeStamps (at composition) = actual value
+ * timeScale (at composition) = actual value / N
+ * (when parser re-generates timestamps, they will be
+ * up-scaled by factor N, which results in slow-motion)
+ *
+ * HSR is a high-framerate recording variant where timestamps
+ * are not meddled with, yielding a video mux'ed at captured
+ * fps
+ */
+ struct HFR {
+ // set kKeyHFR when 'video-hfr' paramater is enabled
+ // or set kKeyHSR when 'video-hsr' paramater is enabled
+ virtual void setHFRIfEnabled(
+ const CameraParameters& params, sp<MetaData> &meta);
+
+ // recalculate file-duration when HFR is enabled
+ virtual status_t initializeHFR(
+ const sp<MetaData> &meta, sp<AMessage> &format,
+ int64_t &maxFileDurationUs, video_encoder videoEncoder);
+
+ virtual void setHFRRatio(
+ sp<MetaData> &meta, const int32_t hfrRatio);
+
+ virtual int32_t getHFRRatio(
+ const sp<MetaData> &meta);
+
+ protected:
+ HFR() {};
+ virtual ~HFR() {};
+ friend struct AVUtils;
+
+ private:
+ // Query supported capabilities from target-specific profiles
+ virtual int32_t getHFRCapabilities(
+ video_encoder codec,
+ int& maxHFRWidth, int& maxHFRHeight, int& maxHFRFps,
+ int& maxBitrate);
+ };
+ virtual inline HFR& HFRUtils() {
+ return mHFR;
+ }
+
private:
HEVCMuxer mHEVCMuxer;
+ HFR mHFR;
// ----- NO TRESSPASSING BEYOND THIS LINE ------
DECLARE_LOADABLE_SINGLETON(AVUtils);
-};
+};
}
#endif // _AV_EXTENSIONS__H_
diff --git a/media/libavextensions/stagefright/AVUtils.cpp b/media/libavextensions/stagefright/AVUtils.cpp
index 35ae36b..298434f 100644
--- a/media/libavextensions/stagefright/AVUtils.cpp
+++ b/media/libavextensions/stagefright/AVUtils.cpp
@@ -41,6 +41,7 @@
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/Utils.h>
+#include <media/MediaProfiles.h>
#if defined(QCOM_HARDWARE) || defined(FLAC_OFFLOAD_ENABLED)
#include "QCMediaDefs.h"
@@ -974,6 +975,130 @@ void AVUtils::setIntraPeriod(
return;
}
+void AVUtils::HFR::setHFRIfEnabled(
+ const CameraParameters& params,
+ sp<MetaData> &meta) {
+ const char *hfrParam = params.get("video-hfr");
+ int32_t hfr = -1;
+ if (hfrParam != NULL) {
+ hfr = atoi(hfrParam);
+ if (hfr > 0) {
+ ALOGI("Enabling HFR @ %d fps", hfr);
+ meta->setInt32(kKeyHFR, hfr);
+ return;
+ } else {
+ ALOGI("Invalid HFR rate specified : %d", hfr);
+ }
+ }
+
+ const char *hsrParam = params.get("video-hsr");
+ int32_t hsr = -1;
+ if (hsrParam != NULL ) {
+ hsr = atoi(hsrParam);
+ if (hsr > 0) {
+ ALOGI("Enabling HSR @ %d fps", hsr);
+ meta->setInt32(kKeyHSR, hsr);
+ } else {
+ ALOGI("Invalid HSR rate specified : %d", hfr);
+ }
+ }
+}
+
+status_t AVUtils::HFR::initializeHFR(
+ const sp<MetaData> &meta, sp<AMessage> &format,
+ int64_t & /*maxFileDurationUs*/, video_encoder videoEncoder) {
+ status_t retVal = OK;
+
+ int32_t hsr = 0;
+ if (meta->findInt32(kKeyHSR, &hsr) && hsr > 0) {
+ ALOGI("HSR cue found. Override encode fps to %d", hsr);
+ format->setInt32("frame-rate", hsr);
+ return retVal;
+ }
+
+ int32_t hfr = 0;
+ if (!meta->findInt32(kKeyHFR, &hfr) || (hfr <= 0)) {
+ ALOGW("Invalid HFR rate specified");
+ return retVal;
+ }
+
+ int32_t width = 0, height = 0;
+ CHECK(meta->findInt32(kKeyWidth, &width));
+ CHECK(meta->findInt32(kKeyHeight, &height));
+
+ int maxW, maxH, MaxFrameRate, maxBitRate = 0;
+ if (getHFRCapabilities(videoEncoder,
+ maxW, maxH, MaxFrameRate, maxBitRate) < 0) {
+ ALOGE("Failed to query HFR target capabilities");
+ return ERROR_UNSUPPORTED;
+ }
+
+ if ((width * height * hfr) > (maxW * maxH * MaxFrameRate)) {
+ ALOGE("HFR request [%d x %d @%d fps] exceeds "
+ "[%d x %d @%d fps]. Will stay disabled",
+ width, height, hfr, maxW, maxH, MaxFrameRate);
+ return ERROR_UNSUPPORTED;
+ }
+
+ int32_t frameRate = 0, bitRate = 0;
+ CHECK(meta->findInt32(kKeyFrameRate, &frameRate));
+ CHECK(format->findInt32("bitrate", &bitRate));
+
+ if (frameRate) {
+ // scale the bitrate proportional to the hfr ratio
+ // to maintain quality, but cap it to max-supported.
+ bitRate = (hfr * bitRate) / frameRate;
+ bitRate = bitRate > maxBitRate ? maxBitRate : bitRate;
+ format->setInt32("bitrate", bitRate);
+
+ int32_t hfrRatio = hfr / frameRate;
+ format->setInt32("frame-rate", hfr);
+ format->setInt32("hfr-ratio", hfrRatio);
+ } else {
+ ALOGE("HFR: Invalid framerate");
+ return BAD_VALUE;
+ }
+
+ return retVal;
+}
+
+void AVUtils::HFR::setHFRRatio(
+ sp<MetaData> &meta, const int32_t hfrRatio) {
+ if (hfrRatio > 0) {
+ meta->setInt32(kKeyHFR, hfrRatio);
+ }
+}
+
+int32_t AVUtils::HFR::getHFRRatio(
+ const sp<MetaData> &meta) {
+ int32_t hfrRatio = 0;
+ meta->findInt32(kKeyHFR, &hfrRatio);
+ return hfrRatio ? hfrRatio : 1;
+}
+
+int32_t AVUtils::HFR::getHFRCapabilities(
+ video_encoder codec,
+ int& maxHFRWidth, int& maxHFRHeight, int& maxHFRFps,
+ int& maxBitRate) {
+ maxHFRWidth = maxHFRHeight = maxHFRFps = maxBitRate = 0;
+ MediaProfiles *profiles = MediaProfiles::getInstance();
+
+ if (profiles) {
+ maxHFRWidth = profiles->getVideoEncoderParamByName("enc.vid.hfr.width.max", codec);
+ maxHFRHeight = profiles->getVideoEncoderParamByName("enc.vid.hfr.height.max", codec);
+ maxHFRFps = profiles->getVideoEncoderParamByName("enc.vid.hfr.mode.max", codec);
+ maxBitRate = profiles->getVideoEncoderParamByName("enc.vid.bps.max", codec);
+ }
+
+ return (maxHFRWidth > 0) && (maxHFRHeight > 0) &&
+ (maxHFRFps > 0) && (maxBitRate > 0) ? 1 : -1;
+}
+
+void AVUtils::extractCustomCameraKeys(
+ const CameraParameters& params, sp<MetaData> &meta) {
+ mHFR.setHFRIfEnabled(params, meta);
+}
+
// ----- NO TRESSPASSING BEYOND THIS LINE ------
AVUtils::AVUtils() {}