diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2015-09-25 12:52:53 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2015-09-25 12:52:53 -0700 |
commit | 04d09607452175eadd1a5c0386d25320833c4a5d (patch) | |
tree | 76586418af2b8c795b8bdf969c5e6f5821fa9819 | |
parent | a9bf34210638317816a7bbf3126b13691de9d732 (diff) | |
parent | 3917d4d929d4c44a79b16fcc7a7c019c4fe2534e (diff) | |
download | android_hardware_qcom_media-04d09607452175eadd1a5c0386d25320833c4a5d.tar.gz android_hardware_qcom_media-04d09607452175eadd1a5c0386d25320833c4a5d.tar.bz2 android_hardware_qcom_media-04d09607452175eadd1a5c0386d25320833c4a5d.zip |
Merge "Merge commit 'a2d1c30003b9723094e0e01f15f9db40cb327730' into private_redfox64_mbr_1"
-rw-r--r-- | mm-video-v4l2/vidc/vdec/inc/omx_vdec.h | 9 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp | 41 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/venc/Android.mk | 1 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h | 7 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/venc/src/neon.c | 93 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp | 52 |
6 files changed, 187 insertions, 16 deletions
diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h index d632ec5d..399d867f 100644 --- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h +++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h @@ -334,8 +334,8 @@ struct debug_cap { }; struct dynamic_buf_list { - OMX_U32 fd; - OMX_U32 dup_fd; + long fd; + long dup_fd; OMX_U32 offset; OMX_U32 ref_count; }; @@ -477,8 +477,8 @@ class omx_vdec: public qc_omx_component pthread_t msg_thread_id; pthread_t async_thread_id; bool is_component_secure(); - void buf_ref_add(OMX_U32 fd, OMX_U32 offset); - void buf_ref_remove(OMX_U32 fd, OMX_U32 offset); + void buf_ref_add(long fd, OMX_U32 offset); + void buf_ref_remove(long fd, OMX_U32 offset); private: // Bit Positions @@ -1077,6 +1077,7 @@ class omx_vdec: public qc_omx_component OMX_TICKS m_last_rendered_TS; volatile int32_t m_queued_codec_config_count; bool secure_scaling_to_non_secure_opb; + bool m_is_display_session; class perf_lock { private: pthread_mutex_t mlock; diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp index 6f6f7ab7..2099b3ea 100644 --- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp +++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp @@ -66,6 +66,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif #include <qdMetaData.h> +#include <gralloc_priv.h> #ifdef ANDROID_JELLYBEAN_MR2 #include "QComOMXMetadata.h" @@ -594,7 +595,8 @@ omx_vdec::omx_vdec(): m_error_propogated(false), stereo_output_mode(HAL_NO_3D), m_last_rendered_TS(-1), m_queued_codec_config_count(0), - secure_scaling_to_non_secure_opb(false) + secure_scaling_to_non_secure_opb(false), + m_is_display_session(false) { /* Assumption is that , to begin with , we have all the frames with decoder */ DEBUG_PRINT_HIGH("In %u bit OMX vdec Constructor", (unsigned int)sizeof(long) * 8); @@ -930,21 +932,28 @@ int omx_vdec::decide_downscalar() return rc; } - DEBUG_PRINT_HIGH("%s: driver wxh = %dx%d, downscalar wxh = %dx%d", __func__, - fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, m_downscalar_width, m_downscalar_height); + DEBUG_PRINT_HIGH("%s: driver wxh = %dx%d, downscalar wxh = %dx%d m_is_display_session = %d", __func__, + fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, m_downscalar_width, m_downscalar_height, m_is_display_session); - if (fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height > m_downscalar_width * m_downscalar_height) { + if ((fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height > m_downscalar_width * m_downscalar_height) && + m_is_display_session) { rc = enable_downscalar(); if (rc < 0) return rc; - rc = update_resolution(m_downscalar_width, m_downscalar_height, m_downscalar_width, m_downscalar_height); + OMX_U32 width = m_downscalar_width > fmt.fmt.pix_mp.width ? + fmt.fmt.pix_mp.width : m_downscalar_width; + OMX_U32 height = m_downscalar_height > fmt.fmt.pix_mp.height ? + fmt.fmt.pix_mp.height : m_downscalar_height; + rc = update_resolution(width, height, + VENUS_Y_STRIDE(COLOR_FMT_NV12, width), VENUS_Y_SCANLINES(COLOR_FMT_NV12, height)); if (rc < 0) return rc; } else { rc = disable_downscalar(); if (rc < 0) return rc; - rc = update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.plane_fmt[0].bytesperline, fmt.fmt.pix_mp.plane_fmt[0].reserved[0]); + rc = update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, + fmt.fmt.pix_mp.plane_fmt[0].bytesperline, fmt.fmt.pix_mp.plane_fmt[0].reserved[0]); if (rc < 0) return rc; } @@ -6586,6 +6595,14 @@ OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, //We'll restore this size later on, so that it's transparent to client buffer->nFilledLen = 0; buffer->nAllocLen = handle->size; + + if (handle->flags & private_handle_t::PRIV_FLAGS_DISP_CONSUMER) { + m_is_display_session = true; + } else { + m_is_display_session = false; + } + DEBUG_PRINT_LOW("%s: m_is_display_session = %d", __func__, m_is_display_session); + } @@ -9095,6 +9112,10 @@ OMX_ERRORTYPE omx_vdec::allocate_output_headers() if (dynamic_buf_mode) { out_dynamic_list = (struct dynamic_buf_list *) \ calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount); + if (out_dynamic_list) { + for (unsigned int i = 0; i < drv_ctx.op_buf.actualcount; i++) + out_dynamic_list[i].dup_fd = -1; + } } if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer @@ -10620,7 +10641,7 @@ OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::cache_ops( return OMX_ErrorNone; } -void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset) +void omx_vdec::buf_ref_add(long fd, OMX_U32 offset) { unsigned long i = 0; bool buf_present = false; @@ -10650,7 +10671,7 @@ void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset) if (!buf_present) { for (i = 0; i < drv_ctx.op_buf.actualcount; i++) { //search for a entry to insert details of the new buffer - if (out_dynamic_list[i].dup_fd == 0) { + if (out_dynamic_list[i].dup_fd < 0) { out_dynamic_list[i].fd = fd; out_dynamic_list[i].offset = offset; out_dynamic_list[i].dup_fd = dup(fd); @@ -10664,7 +10685,7 @@ void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset) pthread_mutex_unlock(&m_lock); } -void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset) +void omx_vdec::buf_ref_remove(long fd, OMX_U32 offset) { unsigned long i = 0; @@ -10688,7 +10709,7 @@ void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset) close(out_dynamic_list[i].dup_fd); DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %u ref_count = %u", (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count); - out_dynamic_list[i].dup_fd = 0; + out_dynamic_list[i].dup_fd = -1; out_dynamic_list[i].fd = 0; out_dynamic_list[i].offset = 0; } diff --git a/mm-video-v4l2/vidc/venc/Android.mk b/mm-video-v4l2/vidc/venc/Android.mk index c2c30fd0..2dd90163 100644 --- a/mm-video-v4l2/vidc/venc/Android.mk +++ b/mm-video-v4l2/vidc/venc/Android.mk @@ -82,6 +82,7 @@ LOCAL_STATIC_LIBRARIES := libOmxVidcCommon LOCAL_SRC_FILES := src/omx_video_base.cpp LOCAL_SRC_FILES += src/omx_video_encoder.cpp LOCAL_SRC_FILES += src/video_encoder_device_v4l2.cpp +LOCAL_SRC_FILES += src/neon.c include $(BUILD_SHARED_LIBRARY) diff --git a/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h b/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h index ad765eed..71554b0f 100644 --- a/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h +++ b/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h @@ -44,6 +44,11 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define BIT(num) (1 << (num)) #define MAX_HYB_HIERP_LAYERS 6 +extern "C" { + void neon_clip_luma_chroma(unsigned char *, unsigned char *, + unsigned int, unsigned int, unsigned int, unsigned int); +} + enum hier_type { HIER_NONE = 0x0, HIER_P = 0x1, @@ -415,6 +420,7 @@ class venc_dev bool venc_set_operatingrate(OMX_U32 rate); bool venc_set_max_hierp(OMX_U32 hierp_layers); bool venc_set_lowlatency_mode(OMX_BOOL enable); + void venc_clip_luma_chroma(int fd, OMX_U32 offset, OMX_U32 size); #ifdef MAX_RES_1080P OMX_U32 pmem_free(); @@ -443,6 +449,7 @@ class venc_dev bool enable_mv_narrow_searchrange; int supported_rc_modes; bool format_set; + char m_platform[OMX_MAX_STRINGNAME_SIZE]; }; enum instance_state { diff --git a/mm-video-v4l2/vidc/venc/src/neon.c b/mm-video-v4l2/vidc/venc/src/neon.c new file mode 100644 index 00000000..e9e90b1d --- /dev/null +++ b/mm-video-v4l2/vidc/venc/src/neon.c @@ -0,0 +1,93 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2015, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +#include <arm_neon.h> + +void neon_clip_luma_chroma(unsigned char *luma, + unsigned char *chroma, unsigned int lv, unsigned int cv, + unsigned int width, unsigned int height) +{ + uint8x16_t PixRow_8x16_1, PixRow_8x16_2, lvv_8x16, cvv_8x16; + unsigned int loop_luma = width * height; + unsigned int loop_chroma = loop_luma/2; + unsigned char *luma_1, *luma_2; + unsigned char *chroma_1, *chroma_2; + unsigned int loop_luma_1 = (loop_luma >> 1)<<1; + unsigned int loop_luma_2 = loop_luma & 1; + unsigned int loop_chroma_1 = (loop_chroma >> 1)<<1; + unsigned int loop_chroma_2 = loop_chroma & 1; + + if (width & 0x1F || height & 0x1F) + return; + + lvv_8x16 = vdupq_n_u8((unsigned char)lv); + cvv_8x16 = vdupq_n_u8((unsigned char)cv); + luma_1 = luma; + chroma_1 = chroma; + + while (loop_luma_1) + { + PixRow_8x16_1 = vld1q_u8(luma_1); + luma_2 = luma_1 + 16; + PixRow_8x16_2 = vld1q_u8(luma_2); + PixRow_8x16_1 = vminq_u8(PixRow_8x16_1, lvv_8x16); + PixRow_8x16_2 = vminq_u8(PixRow_8x16_2, lvv_8x16); + vst1q_u8(luma_1, PixRow_8x16_1); + vst1q_u8(luma_2, PixRow_8x16_2); + luma_1 = luma_1 + 32; + loop_luma_1 = loop_luma_1 - 32; + } + + if (loop_luma_2) + { + PixRow_8x16_1 = vld1q_u8(luma_1); + PixRow_8x16_1 = vminq_u8(PixRow_8x16_1, lvv_8x16); + vst1q_u8(luma_1, PixRow_8x16_1); + } + + while (loop_chroma_1) + { + PixRow_8x16_1 = vld1q_u8(chroma_1); + chroma_2 = chroma_1 + 16; + PixRow_8x16_2 = vld1q_u8(chroma_2); + PixRow_8x16_1 = vminq_u8(PixRow_8x16_1, cvv_8x16); + PixRow_8x16_2 = vminq_u8(PixRow_8x16_2, cvv_8x16); + vst1q_u8(chroma_1, PixRow_8x16_1); + vst1q_u8(chroma_2, PixRow_8x16_2); + chroma_1 = chroma_1 + 32; + loop_chroma_1 = loop_chroma_1 - 32; + } + + if (loop_chroma_2) + { + PixRow_8x16_1 = vld1q_u8(chroma_1); + PixRow_8x16_1 = vminq_u8(PixRow_8x16_1, cvv_8x16); + vst1q_u8(chroma_1, PixRow_8x16_1); + } +} + diff --git a/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp b/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp index 6c520c97..7ece2b5b 100644 --- a/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp +++ b/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp @@ -284,6 +284,11 @@ venc_dev::venc_dev(class omx_venc *venc_class) snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC); + + memset(m_platform, 0, sizeof(m_platform)); + if (property_get("media.msm8956hw", property_value, "0") && atoi(property_value)) { + strncpy(m_platform, "msm8956", sizeof(m_platform)); + } } venc_dev::~venc_dev() @@ -474,9 +479,9 @@ void* venc_dev::async_venc_message_thread (void *input) gettimeofday(&tv,NULL); OMX_U64 time_diff = (OMX_U32)((tv.tv_sec * 1000000 + tv.tv_usec) - (stats.prev_tv.tv_sec * 1000000 + stats.prev_tv.tv_usec)); - if (time_diff >= 5000000) { + OMX_U32 num_fbd = omx->handle->fbd - stats.prev_fbd; + if (num_fbd && time_diff >= 5000000) { if (stats.prev_tv.tv_sec) { - OMX_U32 num_fbd = omx->handle->fbd - stats.prev_fbd; float framerate = num_fbd * 1000000/(float)time_diff; OMX_U32 bitrate = (stats.bytes_generated * 8/num_fbd) * framerate; DEBUG_PRINT_HIGH("stats: avg. fps %0.2f, bitrate %d", @@ -2855,6 +2860,8 @@ bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, } } + venc_clip_luma_chroma(fd, plane.data_offset, plane.bytesused); + buf.index = index; buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; buf.memory = V4L2_MEMORY_USERPTR; @@ -5529,3 +5536,44 @@ bool venc_dev::venc_is_video_session_supported(unsigned long width, DEBUG_PRINT_LOW("video session supported"); return true; } + +void venc_dev::venc_clip_luma_chroma(int fd, OMX_U32 offset, OMX_U32 size) +{ + unsigned char *luma = NULL, *chroma = NULL; + unsigned int alignedWidth = 0, alignedHeight = 0; + + if (strncmp(m_platform, "msm8956", 7)) { + /* return as platform is not msm8956 */ + return; + } + + /* + * limit the pixels in YUV buffer between 0 and 252 for luma and + * 0 and 253 for chroma to avoid output video corruption due to + * video hardware limitation on msm8956 for mpeg4 encoding usecase. + */ + if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_MPEG4) + return; + + if (size < VENUS_BUFFER_SIZE(COLOR_FMT_NV12, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height)) { + DEBUG_PRINT_HIGH("%s: Insufficient buffer size (%u)",__func__, size); + return; + } + + alignedWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, m_sVenc_cfg.input_width); + alignedHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, m_sVenc_cfg.input_height); + + luma = (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE, + MAP_SHARED, fd, offset); + if(luma == MAP_FAILED) { + DEBUG_PRINT_ERROR("MMAP FAILED: returning from %s",__func__); + return; + } + chroma = luma + alignedWidth * alignedHeight; + DEBUG_PRINT_LOW("Clip pixels wxh = %ux%u, size = %u", alignedWidth, alignedHeight, size); + neon_clip_luma_chroma(luma, chroma, 252, 253, alignedWidth, alignedHeight); + DEBUG_PRINT_LOW("Clip pixels done"); + munmap(luma, size); + + return; +} |