diff options
author | Malathi Gottam <quic_mgottam@quicinc.com> | 2023-09-01 16:48:38 +0530 |
---|---|---|
committer | Murtuza Raja <quic_mraja@quicinc.com> | 2023-09-11 23:47:33 +0530 |
commit | af2fef14b510e43ebd202311ea9af22d438f5dc2 (patch) | |
tree | d99cc23f5866579ba062459958034b4d5366c976 | |
parent | 81f05d3be209b6860c63095f925f3fe65b76ca0e (diff) |
screenrecord: get codec capabilities & limit frame rate configuration
Screenrecord is using display refresh rate and configuring it as
framerate for any dimensions (width*height) set. But few devices may
not support this fps for given resolution causing encoder config
failure. To avoid such issues, obtain corresponding performance point
value and limit the frame rate, if its less than display refresh rate.
CRs-Fixed: 3602397
Change-Id: I150590d2ce7d458af20a1740efc37efc1eb867be
-rw-r--r-- | cmds/screenrecord/Android.bp | 1 | ||||
-rw-r--r-- | cmds/screenrecord/screenrecord.cpp | 29 |
2 files changed, 29 insertions, 1 deletions
diff --git a/cmds/screenrecord/Android.bp b/cmds/screenrecord/Android.bp index d0b3ce074f..6e15724941 100644 --- a/cmds/screenrecord/Android.bp +++ b/cmds/screenrecord/Android.bp @@ -43,6 +43,7 @@ cc_binary { "libmedia", "libmediandk", "libmedia_omx", + "libmedia_codeclist", "libutils", "libbinder", "libstagefright_foundation", diff --git a/cmds/screenrecord/screenrecord.cpp b/cmds/screenrecord/screenrecord.cpp index d866c18fe2..e7dae65b64 100644 --- a/cmds/screenrecord/screenrecord.cpp +++ b/cmds/screenrecord/screenrecord.cpp @@ -49,16 +49,20 @@ #include <gui/SurfaceComposerClient.h> #include <gui/ISurfaceComposer.h> #include <media/MediaCodecBuffer.h> +#include <media/MediaCodecInfo.h> #include <media/NdkMediaCodec.h> #include <media/NdkMediaFormatPriv.h> #include <media/NdkMediaMuxer.h> #include <media/openmax/OMX_IVCommon.h> #include <media/stagefright/MediaCodec.h> #include <media/stagefright/MediaCodecConstants.h> +#include <media/stagefright/MediaCodecList.h> +#include <media/stagefright/MediaCodecListOverrides.h> #include <media/stagefright/MediaErrors.h> #include <media/stagefright/PersistentSurface.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/AMessage.h> +#include <media/stagefright/foundation/AUtils.h> #include <mediadrm/ICrypto.h> #include <ui/DisplayMode.h> #include <ui/DisplayState.h> @@ -75,9 +79,12 @@ using android::ui::DisplayMode; using android::FrameOutput; using android::IBinder; using android::IGraphicBufferProducer; +using android::IMediaCodecList; using android::ISurfaceComposer; using android::MediaCodec; using android::MediaCodecBuffer; +using android::MediaCodecList; +using android::MediaCodecInfo; using android::Overlay; using android::PersistentSurface; using android::PhysicalDisplayId; @@ -197,7 +204,6 @@ static status_t prepareEncoder(float displayFps, sp<MediaCodec>* pCodec, format->setString(KEY_MIME, kMimeTypeAvc); format->setInt32(KEY_COLOR_FORMAT, OMX_COLOR_FormatAndroidOpaque); format->setInt32(KEY_BIT_RATE, gBitRate); - format->setFloat(KEY_FRAME_RATE, displayFps); format->setInt32(KEY_I_FRAME_INTERVAL, 10); format->setInt32(KEY_MAX_B_FRAMES, gBframes); if (gBframes > 0) { @@ -226,6 +232,27 @@ static status_t prepareEncoder(float displayFps, sp<MediaCodec>* pCodec, } } + // set frame-rate based on codec capability + const sp<IMediaCodecList> mcl = MediaCodecList::getInstance(); + AString codecName; + codec->getName(&codecName); + ssize_t codecIdx = mcl->findCodecByName(codecName.c_str()); + sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx); + sp<MediaCodecInfo::Capabilities> capabilities = info->getCapabilitiesFor(kMimeTypeAvc); + const sp<AMessage> &details = capabilities->getDetails(); + std::string perfPointKey = "performance-point-" + std::to_string(gVideoWidth) + "x" + + std::to_string(gVideoHeight) + "-range"; + AString minPerfPoint, maxPerfPoint; + AString perfPoint; + if (details->findString(perfPointKey.c_str(), &perfPoint) + && splitString(perfPoint, "-", &minPerfPoint, &maxPerfPoint)) { + int perfPointValue = strtol(maxPerfPoint.c_str(), NULL, 10); + if (perfPointValue < displayFps) { + displayFps = perfPointValue; + } + } + format->setFloat(KEY_FRAME_RATE, displayFps); + err = codec->configure(format, NULL, NULL, MediaCodec::CONFIGURE_FLAG_ENCODE); if (err != NO_ERROR) { |