summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2015-09-25 12:52:53 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2015-09-25 12:52:53 -0700
commit04d09607452175eadd1a5c0386d25320833c4a5d (patch)
tree76586418af2b8c795b8bdf969c5e6f5821fa9819
parenta9bf34210638317816a7bbf3126b13691de9d732 (diff)
parent3917d4d929d4c44a79b16fcc7a7c019c4fe2534e (diff)
downloadandroid_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.h9
-rw-r--r--mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp41
-rw-r--r--mm-video-v4l2/vidc/venc/Android.mk1
-rw-r--r--mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h7
-rw-r--r--mm-video-v4l2/vidc/venc/src/neon.c93
-rw-r--r--mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp52
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;
+}