summaryrefslogtreecommitdiff
path: root/msm8974
diff options
context:
space:
mode:
authorPraveen Chavan <pchavan@codeaurora.org>2016-03-30 00:19:58 -0700
committerLajos Molnar <lajos@google.com>2016-08-25 11:01:00 -0700
commit03783f82008b7447073e0da4550da02bdc2286cf (patch)
tree5dd97f92baa30476a11c9dff90e25c861d92d1b4 /msm8974
parentbfdb1adb7ea840c4c0a9e0c9ad8ebc0ecd43919a (diff)
downloadmedia-03783f82008b7447073e0da4550da02bdc2286cf.tar.gz
mm-video-v4l2: venc: add support for encoding with temporal layers
Implement OMX_IndexParamAndroidVideoTemporalLayers to expose configuration of temporal-layered encoding to client. Layer-wise bitrate support and changing layer-count dynamically is not supported. Bug: 27596987 Change-Id: Ib32e7aea22e2cbaf78a903561b67de7d14ed57e5
Diffstat (limited to 'msm8974')
-rw-r--r--msm8974/mm-core/inc/OMX_IndexExt.h2
-rw-r--r--msm8974/mm-core/inc/OMX_VideoExt.h89
-rw-r--r--msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_base.h4
-rw-r--r--msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h2
-rw-r--r--msm8974/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h15
-rw-r--r--msm8974/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp21
-rw-r--r--msm8974/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp32
-rw-r--r--msm8974/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp152
8 files changed, 315 insertions, 2 deletions
diff --git a/msm8974/mm-core/inc/OMX_IndexExt.h b/msm8974/mm-core/inc/OMX_IndexExt.h
index 3f278ba..c584c08 100644
--- a/msm8974/mm-core/inc/OMX_IndexExt.h
+++ b/msm8974/mm-core/inc/OMX_IndexExt.h
@@ -73,6 +73,8 @@ typedef enum OMX_INDEXEXTTYPE {
OMX_IndexParamVideoHevc, /**< reference: OMX_VIDEO_PARAM_HEVCTYPE */
OMX_IndexParamSliceSegments, /**< reference: OMX_VIDEO_SLICESEGMENTSTYPE */
OMX_IndexConfigAndroidIntraRefresh, /**< reference: OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE */
+ OMX_IndexParamAndroidVideoTemporalLayering, /**< reference: OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE */
+ OMX_IndexConfigAndroidVideoTemporalLayering, /**< reference: OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE */
/* Image & Video common configurations */
OMX_IndexExtCommonStartUnused = OMX_IndexKhronosExtensions + 0x00700000,
diff --git a/msm8974/mm-core/inc/OMX_VideoExt.h b/msm8974/mm-core/inc/OMX_VideoExt.h
index 30fe514..9ea4828 100644
--- a/msm8974/mm-core/inc/OMX_VideoExt.h
+++ b/msm8974/mm-core/inc/OMX_VideoExt.h
@@ -174,6 +174,95 @@ typedef struct OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE {
OMX_U32 nRefreshPeriod;
} OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE;
+/** Maximum number of temporal layers supported by AVC/HEVC */
+#define OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS 8
+
+/** temporal layer patterns */
+typedef enum OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE {
+ OMX_VIDEO_AndroidTemporalLayeringPatternNone = 0,
+ // pattern as defined by WebRTC
+ OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC = 1 << 0,
+ // pattern where frames in any layer other than the base layer only depend on at most the very
+ // last frame from each preceding layer (other than the base layer.)
+ OMX_VIDEO_AndroidTemporalLayeringPatternAndroid = 1 << 1,
+} OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE;
+
+/**
+ * Android specific param for configuration of temporal layering.
+ * Android only supports temporal layering where successive layers each double the
+ * previous layer's framerate.
+ * NOTE: Reading this parameter at run-time SHALL return actual run-time values.
+ *
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to (output port for encoders)
+ * eSupportedPatterns : A bitmask of supported layering patterns
+ * nLayerCountMax : Max number of temporal coding layers supported
+ * by the encoder (must be at least 1, 1 meaning temporal layering
+ * is NOT supported)
+ * nBLayerCountMax : Max number of layers that can contain B frames
+ * (0) to (nLayerCountMax - 1)
+ * ePattern : Layering pattern.
+ * nPLayerCountActual : Number of temporal layers to be coded with non-B frames,
+ * starting from and including the base-layer.
+ * (1 to nLayerCountMax - nBLayerCountActual)
+ * If nPLayerCountActual is 1 and nBLayerCountActual is 0, temporal
+ * layering is disabled. Otherwise, it is enabled.
+ * nBLayerCountActual : Number of temporal layers to be coded with B frames,
+ * starting after non-B layers.
+ * (0 to nBLayerCountMax)
+ * bBitrateRatiosSpecified : Flag to indicate if layer-wise bitrate
+ * distribution is specified.
+ * nBitrateRatios : Bitrate ratio (100 based) per layer (index 0 is base layer).
+ * Honored if bBitrateRatiosSpecified is set.
+ * i.e for 4 layers with desired distribution (25% 25% 25% 25%),
+ * nBitrateRatio = {25, 50, 75, 100, ... }
+ * Values in indices not less than 'the actual number of layers
+ * minus 1' MAY be ignored and assumed to be 100.
+*/
+typedef struct OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE eSupportedPatterns;
+ OMX_U32 nLayerCountMax;
+ OMX_U32 nBLayerCountMax;
+ OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE ePattern;
+ OMX_U32 nPLayerCountActual;
+ OMX_U32 nBLayerCountActual;
+ OMX_BOOL bBitrateRatiosSpecified;
+ OMX_U32 nBitrateRatios[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
+} OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE;
+
+/**
+ * Android specific config for changing the temporal-layer count or
+ * bitrate-distribution at run-time.
+ *
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to (output port for encoders)
+ * ePattern : Layering pattern.
+ * nPLayerCountActual : Number of temporal layers to be coded with non-B frames.
+ * (same OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE limits apply.)
+ * nBLayerCountActual : Number of temporal layers to be coded with B frames.
+ * (same OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE limits apply.)
+ * bBitrateRatiosSpecified : Flag to indicate if layer-wise bitrate
+ * distribution is specified.
+ * nBitrateRatios : Bitrate ratio (100 based, Q16 values) per layer (0 is base layer).
+ * Honored if bBitrateRatiosSpecified is set.
+ * (same OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE limits apply.)
+ */
+typedef struct OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE ePattern;
+ OMX_U32 nPLayerCountActual;
+ OMX_U32 nBLayerCountActual;
+ OMX_BOOL bBitrateRatiosSpecified;
+ OMX_U32 nBitrateRatios[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
+} OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE;
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_base.h b/msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
index 5916582..e75bfcb 100644
--- a/msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
+++ b/msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
@@ -240,6 +240,8 @@ class omx_video: public qc_omx_component
virtual bool dev_get_performance_level(OMX_U32 *) = 0;
virtual bool dev_get_vui_timing_info(OMX_U32 *) = 0;
virtual bool dev_get_peak_bitrate(OMX_U32 *) = 0;
+ virtual bool dev_get_temporal_layer_caps(OMX_U32 * /*nMaxLayers*/,
+ OMX_U32 * /*nMaxBLayers*/) = 0;
#ifdef _ANDROID_ICS_
void omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer);
#endif
@@ -616,6 +618,8 @@ class omx_video: public qc_omx_component
OMX_VIDEO_VP8REFERENCEFRAMETYPE m_sConfigVp8ReferenceFrame;
QOMX_VIDEO_HIERARCHICALLAYERS m_sHierLayers;
QOMX_EXTNINDEX_VIDEO_INITIALQP m_sParamInitqp;
+ OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE m_sParamTemporalLayers;
+ OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE m_sConfigTemporalLayers;
OMX_U32 m_sExtraData;
OMX_U32 m_input_msg_id;
OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE m_sConfigIntraRefresh;
diff --git a/msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h b/msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h
index d7b21db..73a5d33 100644
--- a/msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h
+++ b/msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h
@@ -87,6 +87,8 @@ class omx_venc: public omx_video
bool dev_get_performance_level(OMX_U32 *);
bool dev_get_vui_timing_info(OMX_U32 *);
bool dev_get_peak_bitrate(OMX_U32 *);
+ bool dev_get_temporal_layer_caps(OMX_U32 * /*nMaxLayers*/,
+ OMX_U32 * /*nMaxBLayers*/);
bool dev_is_video_session_supported(OMX_U32 width, OMX_U32 height);
bool dev_color_align(OMX_BUFFERHEADERTYPE *buffer, OMX_U32 width,
OMX_U32 height);
diff --git a/msm8974/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h b/msm8974/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
index e2bdaf7..94d68ee 100644
--- a/msm8974/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
+++ b/msm8974/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
@@ -219,6 +219,16 @@ struct msm_venc_priority {
OMX_U32 priority;
};
+struct msm_venc_temporal_layers {
+ enum hier_type hier_mode;
+ OMX_U32 nMaxLayers;
+ OMX_U32 nMaxBLayers;
+ OMX_U32 nPLayers;
+ OMX_U32 nBLayers;
+ OMX_BOOL bIsBitrateRatioValid;
+ OMX_U32 nTemporalLayerBitrateRatio[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
+};
+
enum v4l2_ports {
CAPTURE_PORT,
OUTPUT_PORT,
@@ -288,6 +298,8 @@ class venc_dev
bool venc_get_performance_level(OMX_U32 *perflevel);
bool venc_get_vui_timing_info(OMX_U32 *enabled);
bool venc_get_peak_bitrate(OMX_U32 *peakbitrate);
+ bool venc_get_temporal_layer_caps(OMX_U32 * /*nMaxLayers*/,
+ OMX_U32 * /*nMaxBLayers*/);
bool venc_get_output_log_flag();
int venc_output_log_buffers(const char *buffer_addr, int buffer_len);
int venc_input_log_buffers(OMX_BUFFERHEADERTYPE *buffer, int fd, int plane_offset);
@@ -358,6 +370,7 @@ class venc_dev
struct msm_venc_vpx_error_resilience vpx_err_resilience;
struct msm_venc_priority sess_priority;
OMX_U32 operating_rate;
+ msm_venc_temporal_layers temporal_layers_config;
bool venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel);
bool venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames);
@@ -400,6 +413,8 @@ class venc_dev
bool venc_validate_hybridhp_params(OMX_U32 layers, OMX_U32 bFrames, OMX_U32 count, int mode);
bool venc_set_session_priority(OMX_U32 priority);
bool venc_set_operatingrate(OMX_U32 rate);
+ OMX_ERRORTYPE venc_set_temporal_layers(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalParams);
+ OMX_ERRORTYPE venc_set_temporal_layers_internal();
#ifdef MAX_RES_1080P
OMX_U32 pmem_free();
diff --git a/msm8974/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp b/msm8974/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
index 6e7e05a..9c71157 100644
--- a/msm8974/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
+++ b/msm8974/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
@@ -1910,6 +1910,19 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
memcpy(initqp, &m_sParamInitqp, sizeof(m_sParamInitqp));
break;
}
+ case OMX_IndexParamAndroidVideoTemporalLayering:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE);
+ OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pLayerInfo =
+ reinterpret_cast<OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*>(paramData);
+ if (!dev_get_temporal_layer_caps(&m_sParamTemporalLayers.nLayerCountMax,
+ &m_sParamTemporalLayers.nBLayerCountMax)) {
+ DEBUG_PRINT_ERROR("Failed to get temporal layer capabilities");
+ eRet = OMX_ErrorHardware;
+ }
+ memcpy(pLayerInfo, &m_sParamTemporalLayers, sizeof(m_sParamTemporalLayers));
+ break;
+ }
case OMX_IndexParamVideoSliceFMO:
default:
{
@@ -2042,6 +2055,14 @@ OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp,
memcpy(pParam, &m_sConfigIntraRefresh, sizeof(m_sConfigIntraRefresh));
break;
}
+ case OMX_IndexParamAndroidVideoTemporalLayering:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE);
+ OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *layerConfig =
+ (OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *)configData;
+ memcpy(configData, &m_sConfigTemporalLayers, sizeof(m_sConfigTemporalLayers));
+ break;
+ }
default:
DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
return OMX_ErrorUnsupportedIndex;
diff --git a/msm8974/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp b/msm8974/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
index 33a147b..1da8627 100644
--- a/msm8974/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
+++ b/msm8974/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
@@ -470,6 +470,13 @@ OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role)
m_sHierLayers.nNumLayers = 0;
m_sHierLayers.eHierarchicalCodingType = QOMX_HIERARCHICALCODING_P;
+ memset(&m_sParamTemporalLayers, 0x0, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
+ OMX_INIT_STRUCT(&m_sParamTemporalLayers, OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE);
+ m_sParamTemporalLayers.eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
+
+ memset(&m_sConfigTemporalLayers, 0x0, sizeof(OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE));
+ OMX_INIT_STRUCT(&m_sConfigTemporalLayers, OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE);
+
m_state = OMX_StateLoaded;
m_sExtraData = 0;
@@ -1477,6 +1484,26 @@ OMX_ERRORTYPE omx_venc::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
}
break;
}
+ case OMX_IndexParamAndroidVideoTemporalLayering:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE);
+ if (!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering)) {
+ DEBUG_PRINT_ERROR("Failed to configure temporal layers");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ // save the actual configuration applied
+ memcpy(&m_sParamTemporalLayers, paramData, sizeof(m_sParamTemporalLayers));
+ // keep the config data in sync
+ m_sConfigTemporalLayers.ePattern = m_sParamTemporalLayers.ePattern;
+ m_sConfigTemporalLayers.nBLayerCountActual = m_sParamTemporalLayers.nBLayerCountActual;
+ m_sConfigTemporalLayers.nPLayerCountActual = m_sParamTemporalLayers.nPLayerCountActual;
+ m_sConfigTemporalLayers.bBitrateRatiosSpecified = m_sParamTemporalLayers.bBitrateRatiosSpecified;
+ memcpy(&m_sConfigTemporalLayers.nBitrateRatios[0],
+ &m_sParamTemporalLayers.nBitrateRatios[0],
+ OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS * sizeof(OMX_U32));
+ break;
+ }
case OMX_IndexParamVideoSliceFMO:
default:
{
@@ -2074,6 +2101,11 @@ bool omx_venc::dev_get_peak_bitrate(OMX_U32 *peakbitrate)
#endif
}
+bool omx_venc::dev_get_temporal_layer_caps(OMX_U32 *nMaxLayers,
+ OMX_U32 *nMaxBLayers) {
+ return handle->venc_get_temporal_layer_caps(nMaxLayers, nMaxBLayers);
+}
+
bool omx_venc::dev_loaded_start()
{
return handle->venc_loaded_start();
diff --git a/msm8974/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp b/msm8974/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
index cd3ba9f..cc8d6ae 100644
--- a/msm8974/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
+++ b/msm8974/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
@@ -255,6 +255,7 @@ venc_dev::venc_dev(class omx_venc *venc_class)
memset(&ltrinfo, 0, sizeof(ltrinfo));
sess_priority.priority = 1;
operating_rate = 0;
+ memset(&temporal_layers_config, 0x0, sizeof(temporal_layers_config));
char property_value[PROPERTY_VALUE_MAX] = {0};
property_get("vidc.enc.log.in", property_value, "0");
@@ -1913,6 +1914,15 @@ bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index )
}
break;
}
+ case OMX_IndexParamAndroidVideoTemporalLayering:
+ {
+ if (venc_set_temporal_layers(
+ (OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*)paramData) != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("set_param: Failed to configure temporal layers");
+ return false;
+ }
+ break;
+ }
case OMX_IndexParamVideoSliceFMO:
default:
DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
@@ -2163,6 +2173,11 @@ bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
}
break;
}
+ case OMX_IndexParamAndroidVideoTemporalLayering:
+ {
+ DEBUG_PRINT_ERROR("TemporalLayer: Changing layer-configuration dynamically is not supported!");
+ return false;
+ }
default:
DEBUG_PRINT_ERROR("Unsupported config index = %u", index);
break;
@@ -2300,6 +2315,26 @@ unsigned venc_dev::venc_start(void)
__func__, codec_profile.profile, profile_level.level);
}
+ // re-configure the temporal layers as RC-mode and key-frame interval
+ // might have changed since the client last configured the layers.
+ if (temporal_layers_config.nPLayers) {
+ if (venc_set_temporal_layers_internal() != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("Re-configuring temporal layers failed !");
+ } else {
+ // request buffers on capture port again since internal (scratch)-
+ // buffer requirements may change (i.e if we switch from non-hybrid
+ // to hybrid mode and vice-versa)
+ struct v4l2_requestbuffers bufreq;
+
+ bufreq.memory = V4L2_MEMORY_USERPTR;
+ bufreq.count = m_sOutput_buff_property.actualcount;
+ bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ if (ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq)) {
+ DEBUG_PRINT_ERROR("Request bufs failed while reconfiguring layers");
+ }
+ }
+ }
+
venc_config_print();
if(resume_in_stopped){
@@ -2398,8 +2433,16 @@ void venc_dev::venc_config_print()
DEBUG_PRINT_HIGH("ENC_CONFIG: LTR Enabled: %d, Count: %d",
ltrinfo.enabled, ltrinfo.count);
- DEBUG_PRINT_HIGH("ENC_CONFIG: Hier layers: %d, Hier Mode: %s VPX_ErrorResilience: %d",
- hier_layers.numlayers, hiermode_string(hier_layers.hier_mode), vpx_err_resilience.enable);
+ if (hier_layers.numlayers) {
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Hier layers: %d, Hier Mode: %s VPX_ErrorResilience: %d",
+ hier_layers.numlayers, hiermode_string(hier_layers.hier_mode), vpx_err_resilience.enable);
+ }
+
+ if (temporal_layers_config.nPLayers) {
+ DEBUG_PRINT_INFO("ENC_CONFIG: Temporal layers: P-layers: %u, B-layers: %u, Adjusted I-frame-interval: %u",
+ temporal_layers_config.nPLayers, temporal_layers_config.nBLayers,
+ intra_period.num_pframes + intra_period.num_bframes + 1);
+ }
DEBUG_PRINT_HIGH("ENC_CONFIG: Performace level: %d", performance_level.perflevel);
@@ -4790,6 +4833,111 @@ bool venc_dev::venc_set_operatingrate(OMX_U32 rate) {
return true;
}
+bool venc_dev::venc_get_temporal_layer_caps(OMX_U32 *nMaxLayers,
+ OMX_U32 *nMaxBLayers) {
+ temporal_layers_config.nMaxLayers = MAX_HYB_HIERP_LAYERS; // TODO: get this count from codec
+ temporal_layers_config.nMaxBLayers = 0;
+
+ *nMaxLayers = temporal_layers_config.nMaxLayers;
+ *nMaxBLayers = temporal_layers_config.nMaxBLayers;
+ return true;
+}
+
+OMX_ERRORTYPE venc_dev::venc_set_temporal_layers(
+ OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalParams) {
+
+ if (!(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
+ || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC
+ || m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
+ DEBUG_PRINT_ERROR("Temporal layers not supported for %ld", m_sVenc_cfg.codectype);
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ if (pTemporalParams->ePattern == OMX_VIDEO_AndroidTemporalLayeringPatternNone &&
+ (pTemporalParams->nBLayerCountActual != 0 ||
+ pTemporalParams->nPLayerCountActual != 1)) {
+ return OMX_ErrorBadParameter;
+ } else if (pTemporalParams->ePattern != OMX_VIDEO_AndroidTemporalLayeringPatternAndroid ||
+ pTemporalParams->nPLayerCountActual < 1) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (pTemporalParams->nBLayerCountActual > temporal_layers_config.nMaxBLayers) {
+ DEBUG_PRINT_ERROR("TemporalLayer: Requested B-layers (%u) exceeds supported max(%u)",
+ pTemporalParams->nBLayerCountActual, temporal_layers_config.nMaxBLayers);
+ return OMX_ErrorBadParameter;
+ } else if (pTemporalParams->nPLayerCountActual >
+ temporal_layers_config.nMaxLayers - pTemporalParams->nBLayerCountActual) {
+ DEBUG_PRINT_ERROR("TemporalLayer: Requested layers (%u) exceeds supported max(%u)",
+ pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual,
+ temporal_layers_config.nMaxLayers);
+ return OMX_ErrorBadParameter;
+ }
+
+ // For AVC, if B-layer has not been configured and RC mode is VBR (camcorder),
+ // use hybrid-HP for best results
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 &&
+ pTemporalParams->nBLayerCountActual == 0 &&
+ (rate_ctrl.rcmode == RC_VBR_CFR || rate_ctrl.rcmode == RC_VBR_VFR)) {
+ if (!venc_set_hybrid_hierp(pTemporalParams->nPLayerCountActual)) {
+ DEBUG_PRINT_ERROR("Failed to enable (hybrid) Hier-P with %u layers",
+ pTemporalParams->nPLayerCountActual);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ temporal_layers_config.hier_mode = HIER_P_HYBRID;
+ temporal_layers_config.nPLayers = pTemporalParams->nPLayerCountActual;
+ temporal_layers_config.nBLayers = 0;
+
+ // we ignore layer-size bitrate request for this mode
+ temporal_layers_config.bIsBitrateRatioValid = OMX_FALSE;
+ pTemporalParams->bBitrateRatiosSpecified = OMX_FALSE;
+
+ } else {
+ if (pTemporalParams->nBLayerCountActual == 0) {
+ if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, pTemporalParams->nPLayerCountActual)) {
+ DEBUG_PRINT_ERROR("Failed to enable Hier-P with %u layers",
+ pTemporalParams->nPLayerCountActual);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ temporal_layers_config.hier_mode = HIER_P;
+ temporal_layers_config.nPLayers = pTemporalParams->nPLayerCountActual;
+ temporal_layers_config.nBLayers = 0;
+
+ // TODO: handle layer-wise bitrate request. For now, disregard the setting
+ temporal_layers_config.bIsBitrateRatioValid = OMX_FALSE;
+ pTemporalParams->bBitrateRatiosSpecified = OMX_FALSE;
+
+ } else {
+ // we do not support B-frames with enhancement layers for now
+ }
+ }
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE venc_dev::venc_set_temporal_layers_internal() {
+ OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE pTemporalParams;
+ memset(&pTemporalParams, 0x0, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
+
+ if (!temporal_layers_config.nPLayers) {
+ return OMX_ErrorNone;
+ }
+ pTemporalParams.eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
+ pTemporalParams.nLayerCountMax = temporal_layers_config.nMaxLayers;
+ pTemporalParams.nBLayerCountMax = temporal_layers_config.nMaxBLayers;
+ pTemporalParams.ePattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
+ pTemporalParams.nPLayerCountActual = temporal_layers_config.nPLayers;
+ pTemporalParams.nBLayerCountActual = temporal_layers_config.nBLayers;
+ pTemporalParams.bBitrateRatiosSpecified = temporal_layers_config.bIsBitrateRatioValid;
+ if (temporal_layers_config.bIsBitrateRatioValid == OMX_TRUE) {
+ for (OMX_U32 i = 0; i < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers; ++i) {
+ pTemporalParams.nBitrateRatios[i] =
+ temporal_layers_config.nTemporalLayerBitrateRatio[i];
+ }
+ }
+ return venc_set_temporal_layers(&pTemporalParams);
+}
+
bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
{
bool status = true;