diff options
author | Hangyu Kuang <hkuang@google.com> | 2016-08-09 20:00:22 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2016-08-09 20:00:22 +0000 |
commit | bfdb1adb7ea840c4c0a9e0c9ad8ebc0ecd43919a (patch) | |
tree | f6deb4f597f05a91097a3814feaf3528678935ee /msm8996 | |
parent | 187779f25a339c00d37ff09a478113f0b2047120 (diff) | |
parent | 939bc4145117bc6b87d6cef5c0219c63efff113b (diff) | |
download | media-bfdb1adb7ea840c4c0a9e0c9ad8ebc0ecd43919a.tar.gz |
Merge "mm-video-v4l2: vidc: Fix read/write colorspace from/to gralloc-handle" into nyc-mr1-dev
Diffstat (limited to 'msm8996')
7 files changed, 166 insertions, 56 deletions
diff --git a/msm8996/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/msm8996/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h index 789b08c..d400fc3 100644 --- a/msm8996/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h +++ b/msm8996/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h @@ -670,6 +670,7 @@ class omx_vdec: public qc_omx_component OMX_U32 transfer, OMX_U32 matrix, ColorSpace_t *color_space, ColorAspects *aspects); void handle_color_space_info(void *data, unsigned int buf_index); + void set_colorspace_in_handle(ColorSpace_t color, unsigned int buf_index); void print_debug_color_aspects(ColorAspects *aspects, const char *prefix); void print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra); #ifdef _MSM8974_ diff --git a/msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp b/msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp index 3b4a00b..806521f 100644 --- a/msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp +++ b/msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp @@ -7978,6 +7978,42 @@ OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp, } if (!output_flush_progress && (buffer->nFilledLen > 0)) { + // set the default colorspace advised by client, since the bitstream may be + // devoid of colorspace-info. + if (m_enable_android_native_buffers) { + ColorSpace_t color_space = ITU_R_601; + + // Disabled ? + // WA for VP8. Vp8 encoder does not embed color-info (yet!). + // Encoding RGBA results in 601-LR for all resolutions. + // This conflicts with the client't defaults which are based on resolution. + // Eg: 720p will be encoded as 601-LR. Client will say 709. + // Re-enable this code once vp8 encoder generates color-info and hence the + // decoder will be able to override with the correct source color. +#if 0 + switch (m_client_color_space.sAspects.mPrimaries) { + case ColorAspects::PrimariesBT601_6_625: + case ColorAspects::PrimariesBT601_6_525: + { + color_space = m_client_color_space.sAspects.mRange == ColorAspects::RangeFull ? + ITU_R_601_FR : ITU_R_601; + break; + } + case ColorAspects::PrimariesBT709_5: + { + color_space = ITU_R_709; + break; + } + default: + { + break; + } + } +#endif + DEBUG_PRINT_LOW("setMetaData for Color Space (client) = 0x%x (601=%u FR=%u 709=%u)", + color_space, ITU_R_601, ITU_R_601_FR, ITU_R_709); + set_colorspace_in_handle(color_space, buffer - m_out_mem_ptr); + } DEBUG_PRINT_LOW("Processing extradata"); handle_extradata(buffer); } @@ -10254,9 +10290,8 @@ void omx_vdec::handle_color_space_info(void *data, unsigned int buf_index) break; } if (m_enable_android_native_buffers) { - DEBUG_PRINT_HIGH("setMetaData for Color Space = 0x%x", color_space); - setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, - UPDATE_COLOR_SPACE, (void*)&color_space); + DEBUG_PRINT_HIGH("setMetaData for Color Space = 0x%x (601=%u FR=%u 709=%u)", color_space, ITU_R_601, ITU_R_601_FR, ITU_R_709); + set_colorspace_in_handle(color_space, buf_index); } print_debug_color_aspects(aspects, "Bitstream"); @@ -10277,6 +10312,18 @@ void omx_vdec::handle_color_space_info(void *data, unsigned int buf_index) } } +void omx_vdec::set_colorspace_in_handle(ColorSpace_t color_space, unsigned int buf_index) { + private_handle_t *private_handle = NULL; + if (buf_index < drv_ctx.op_buf.actualcount && + buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS && + native_buffer[buf_index].privatehandle) { + private_handle = native_buffer[buf_index].privatehandle; + } + if (private_handle) { + setMetaData(private_handle, UPDATE_COLOR_SPACE, (void*)&color_space); + } +} + void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) { OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL; diff --git a/msm8996/mm-video-v4l2/vidc/venc/Android.mk b/msm8996/mm-video-v4l2/vidc/venc/Android.mk index d71e1eb..25e9601 100644 --- a/msm8996/mm-video-v4l2/vidc/venc/Android.mk +++ b/msm8996/mm-video-v4l2/vidc/venc/Android.mk @@ -89,6 +89,7 @@ LOCAL_ADDITIONAL_DEPENDENCIES := $(libmm-venc-add-dep) LOCAL_PRELINK_MODULE := false LOCAL_SHARED_LIBRARIES := liblog libutils libbinder libcutils \ libc2dcolorconvert libdl libgui +LOCAL_SHARED_LIBRARIES += libqdMetaData LOCAL_STATIC_LIBRARIES := libOmxVidcCommon LOCAL_SRC_FILES := src/omx_video_base.cpp diff --git a/msm8996/mm-video-v4l2/vidc/venc/inc/omx_video_base.h b/msm8996/mm-video-v4l2/vidc/venc/inc/omx_video_base.h index 4ded11f..351c011 100644 --- a/msm8996/mm-video-v4l2/vidc/venc/inc/omx_video_base.h +++ b/msm8996/mm-video-v4l2/vidc/venc/inc/omx_video_base.h @@ -563,6 +563,7 @@ class omx_video: public qc_omx_component void complete_pending_buffer_done_cbs(); bool is_conv_needed(int, int); + void print_debug_color_aspects(ColorAspects *aspects, const char *prefix); #ifdef USE_ION int alloc_map_ion_memory(int size, diff --git a/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp b/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp index 11286a9..c296f4f 100644 --- a/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp +++ b/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp @@ -2259,7 +2259,27 @@ OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp, DEBUG_PRINT_ERROR("Does not handle dataspace request"); return OMX_ErrorUnsupportedSetting; } - memcpy(pParam, &m_sConfigColorAspects, sizeof(m_sConfigColorAspects)); + if (pParam->bDataSpaceChanged == OMX_TRUE) { + + print_debug_color_aspects(&(pParam->sAspects), "get_config (dataspace changed) Client says"); + // If the dataspace says RGB, recommend 601-limited; + // since that is the destination colorspace that C2D or Venus will convert to. + if (pParam->nPixelFormat == HAL_PIXEL_FORMAT_RGBA_8888) { + DEBUG_PRINT_INFO("get_config (dataspace changed): ColorSpace: Recommend 601-limited for RGBA8888"); + pParam->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625; + pParam->sAspects.mRange = ColorAspects::RangeLimited; + pParam->sAspects.mTransfer = ColorAspects::TransferSMPTE170M; + pParam->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6; + } else { + // For IMPLEMENTATION_DEFINED (or anything else), stick to client's defaults. + DEBUG_PRINT_INFO("get_config (dataspace changed): ColorSpace: use client-default for format=%x", + pParam->nPixelFormat); + } + print_debug_color_aspects(&(pParam->sAspects), "get_config (dataspace changed) recommended"); + } else { + memcpy(pParam, &m_sConfigColorAspects, sizeof(m_sConfigColorAspects)); + print_debug_color_aspects(&(pParam->sAspects), "get_config"); + } break; } default: @@ -4922,6 +4942,11 @@ bool omx_video::is_conv_needed(int hal_fmt, int hal_flags) return bRet; } +void omx_video::print_debug_color_aspects(ColorAspects *aspects, const char *prefix) { + DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d Range = %d Transfer = %d MatrixCoeffs = %d", + prefix, aspects->mPrimaries, aspects->mRange, aspects->mTransfer, aspects->mMatrixCoeffs); +} + OMX_ERRORTYPE omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp, OMX_IN OMX_BUFFERHEADERTYPE* buffer) { diff --git a/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp b/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp index b97eedc..ceacf19 100644 --- a/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp +++ b/msm8996/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp @@ -2095,6 +2095,8 @@ OMX_ERRORTYPE omx_venc::set_config(OMX_IN OMX_HANDLETYPE hComp, case OMX_QTIIndexConfigDescribeColorAspects: { VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams); + DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData; + print_debug_color_aspects(&(params->sAspects), "set_config"); if (!handle->venc_set_config(configData, (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects)) { DEBUG_PRINT_ERROR("Failed to set OMX_QTIIndexConfigDescribeColorAspects"); return OMX_ErrorUnsupportedSetting; diff --git a/msm8996/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp b/msm8996/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp index c34d9a7..76bd24a 100644 --- a/msm8996/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp +++ b/msm8996/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp @@ -2625,21 +2625,16 @@ bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index) case OMX_QTIIndexConfigDescribeColorAspects: { DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData; - DEBUG_PRINT_LOW("OMX_QTIIndexConfigDescribeColorAspects : sAspects.mPrimaries = %d sAspects.mRange = %d" - "sAspects.mTransfer %d, sAspects.mMatrixCoeffs = %d", params->sAspects.mPrimaries, params->sAspects.mRange, - params->sAspects.mTransfer, params->sAspects.mMatrixCoeffs); - OMX_U32 color_space = MSM_VIDC_BT601_6_525; - OMX_U32 full_range = 1; - OMX_U32 matrix_coeffs = MSM_VIDC_MATRIX_601_6_525; - OMX_U32 transfer_chars = MSM_VIDC_TRANSFER_601_6_525; + + OMX_U32 color_space = MSM_VIDC_BT601_6_625; + OMX_U32 full_range = 0; + OMX_U32 matrix_coeffs = MSM_VIDC_MATRIX_601_6_625; + OMX_U32 transfer_chars = MSM_VIDC_TRANSFER_601_6_625; switch((ColorAspects::Primaries)(params->sAspects.mPrimaries)) { case ColorAspects::PrimariesBT709_5: color_space = MSM_VIDC_BT709_5; break; - case ColorAspects::PrimariesUnspecified: - color_space = MSM_VIDC_UNSPECIFIED; - break; case ColorAspects::PrimariesBT470_6M: color_space = MSM_VIDC_BT470_6_M; break; @@ -2656,8 +2651,8 @@ bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index) color_space = MSM_VIDC_BT2020; break; default: - color_space = MSM_VIDC_BT601_6_525; - params->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_525; + color_space = MSM_VIDC_BT601_6_625; + //params->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625; break; } switch((ColorAspects::Range)params->sAspects.mRange) { @@ -2699,8 +2694,8 @@ bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index) transfer_chars = MSM_VIDC_TRANSFER_SRGB; break; default: - params->sAspects.mTransfer = ColorAspects::TransferSMPTE170M; - transfer_chars = MSM_VIDC_TRANSFER_601_6_525; + //params->sAspects.mTransfer = ColorAspects::TransferSMPTE170M; + transfer_chars = MSM_VIDC_TRANSFER_601_6_625; break; } switch((ColorAspects::MatrixCoeffs)params->sAspects.mMatrixCoeffs) { @@ -2726,8 +2721,8 @@ bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index) matrix_coeffs = MSM_VIDC_MATRIX_BT_2020_CONST; break; default: - params->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6; - matrix_coeffs = MSM_VIDC_MATRIX_601_6_525; + //params->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6; + matrix_coeffs = MSM_VIDC_MATRIX_601_6_625; break; } if (!venc_set_colorspace(color_space, full_range, @@ -3506,55 +3501,93 @@ bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, fd, plane[0].bytesused, plane[0].length, buf.flags, m_sVenc_cfg.inputformat); } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) { private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle; - if (!streaming[OUTPUT_PORT]) { - struct v4l2_format fmt; - int color_space = 0; + if (!streaming[OUTPUT_PORT] && handle) { - memset(&fmt, 0, sizeof(fmt)); + // Moment of truth... actual colorspace is known here.. + ColorSpace_t colorSpace = ITU_R_601; + if (getMetaData(handle, GET_COLOR_SPACE, &colorSpace) == 0) { + DEBUG_PRINT_INFO("ENC_CONFIG: gralloc ColorSpace = %d (601=%d 601_FR=%d 709=%d)", + colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709); + } + struct v4l2_format fmt; + memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + + bool isUBWC = (handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) && is_gralloc_source_ubwc; if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE) { - if ((handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) && - is_gralloc_source_ubwc) { - m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC; - } else { - m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12; - } + m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_NV12_UBWC : V4L2_PIX_FMT_NV12; + DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 %s", isUBWC ? "UBWC" : "Linear"); } else if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) { - if ((handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) && - is_gralloc_source_ubwc) { - m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGBA8888_UBWC; - } else { - m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGB32; - } - } else if ( handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) { + // In case of RGB, conversion to YUV is handled within encoder. + // Disregard the Colorspace in gralloc-handle in case of RGB and use + // [a] 601 for non-UBWC case : C2D output is (apparently) 601-LR + // [b] 601 for UBWC case : Venus can convert to 601-LR or FR. use LR for now. + colorSpace = ITU_R_601; + m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_RGBA8888_UBWC : V4L2_PIX_FMT_RGB32; + DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = RGBA8888 %s", isUBWC ? "UBWC" : "Linear"); + } else if (handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) { m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12; + DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 Linear"); } - if (handle->flags & private_handle_t::PRIV_FLAGS_ITU_R_709) { - buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP; - color_space = V4L2_COLORSPACE_REC709; - venc_set_colorspace(MSM_VIDC_BT709_5, 1, - MSM_VIDC_TRANSFER_BT709_5, MSM_VIDC_MATRIX_BT_709_5); - } else { - if (is_csc_enabled) { - struct v4l2_control control; - control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC; - control.value = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE; - if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_ERROR("Failed to set VPE CSC for 601_to_709"); - } + + // If device recommendation (persist.vidc.enc.csc.enable) is to use 709, force CSC + if (colorSpace == ITU_R_601_FR && is_csc_enabled) { + struct v4l2_control control; + control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC; + control.value = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE; + if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_ERROR("venc_empty_buf: Failed to set VPE CSC for 601_to_709"); + } else { + DEBUG_PRINT_INFO("venc_empty_buf: Will convert 601-FR to 709"); buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP; + colorSpace = ITU_R_709; + } + } + + msm_vidc_h264_color_primaries_values primary; + msm_vidc_h264_transfer_chars_values transfer; + msm_vidc_h264_matrix_coeff_values matrix; + OMX_U32 range; + + switch (colorSpace) { + case ITU_R_601_FR: + { + primary = MSM_VIDC_BT601_6_525; + range = 1; // full + transfer = MSM_VIDC_TRANSFER_601_6_525; + matrix = MSM_VIDC_MATRIX_601_6_525; + + fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case ITU_R_709: + { + primary = MSM_VIDC_BT709_5; + range = 0; // limited + transfer = MSM_VIDC_TRANSFER_BT709_5; + matrix = MSM_VIDC_MATRIX_BT_709_5; + fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709; - venc_set_colorspace(MSM_VIDC_BT709_5, 1, - MSM_VIDC_TRANSFER_BT709_5, MSM_VIDC_MATRIX_BT_709_5); - } else { - venc_set_colorspace(MSM_VIDC_BT601_6_525, 1, - MSM_VIDC_TRANSFER_601_6_525, MSM_VIDC_MATRIX_601_6_525); + break; + } + default: + { + // 601 or something else ? assume 601 + primary = MSM_VIDC_BT601_6_625; + range = 0; //limited + transfer = MSM_VIDC_TRANSFER_601_6_625; + matrix = MSM_VIDC_MATRIX_601_6_625; + fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; } } + DEBUG_PRINT_INFO("ENC_CONFIG: selected ColorSpace = %d (601=%d 601_FR=%d 709=%d)", + colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709); + venc_set_colorspace(primary, range, transfer, matrix); + fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat; - fmt.fmt.pix_mp.colorspace = static_cast<decltype(fmt.fmt.pix_mp.colorspace)>(color_space); fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { |