merge in lmp-mr1-release history after reset to lmp-mr1-dev
diff --git a/mm-core/inc/OMX_QCOMExtns.h b/mm-core/inc/OMX_QCOMExtns.h
index a5676bf..1c85a80 100755
--- a/mm-core/inc/OMX_QCOMExtns.h
+++ b/mm-core/inc/OMX_QCOMExtns.h
@@ -468,6 +468,8 @@
QOMX_IndexParamVideoInitialQp = 0x7F00003B,
OMX_QcomIndexParamSetMVSearchrange = 0x7F00003C,
+
+ OMX_QcomIndexFlexibleYUVDescription = 0x7F00003D,
};
/**
diff --git a/mm-video-legacy/vidc/vdec/inc/omx_vdec.h b/mm-video-legacy/vidc/vdec/inc/omx_vdec.h
index 240ffb6..4787b77 100644
--- a/mm-video-legacy/vidc/vdec/inc/omx_vdec.h
+++ b/mm-video-legacy/vidc/vdec/inc/omx_vdec.h
@@ -549,6 +549,7 @@
OMX_PTR appData,
OMX_U32 bytes,
OMX_U8 *buffer);
+
#ifdef MAX_RES_720P
OMX_ERRORTYPE get_supported_profile_level_for_720p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType);
#endif
@@ -844,11 +845,19 @@
OMX_ERRORTYPE allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,
OMX_U32 bytes);
+ OMX_ERRORTYPE use_output_buffer(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE **bufferHdr, OMX_U32 port, OMX_PTR appData,
+ OMX_U32 bytes, OMX_U8 *buffer);
+
OMX_ERRORTYPE free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr);
+ void enable_native_buffers(bool enable) {m_native_buffers_enabled = enable;}
+ OMX_U32 get_output_stride();
+ OMX_U32 get_output_scanlines();
private:
#define MAX_COUNT 32
omx_vdec *omx;
bool enabled;
+ bool m_native_buffers_enabled;
OMX_COLOR_FORMATTYPE ColorFormat;
void init_members();
bool color_convert_mode;
diff --git a/mm-video-legacy/vidc/vdec/src/omx_vdec.cpp b/mm-video-legacy/vidc/vdec/src/omx_vdec.cpp
index 06d333d..ccb3f7a 100644
--- a/mm-video-legacy/vidc/vdec/src/omx_vdec.cpp
+++ b/mm-video-legacy/vidc/vdec/src/omx_vdec.cpp
@@ -146,6 +146,9 @@
#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); }
+#define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1)))
+#define ALIGN32 32
+#define ALIGN16 16
bool omx_vdec::m_secure_display = false;
@@ -2777,7 +2780,7 @@
" NoMore Color formats\n");
eRet = OMX_ErrorNoMore;
}
- ALOGI("get_parameter: color-format=%x @ index=%d", portFmt->eColorFormat, portFmt->nIndex);
+ DEBUG_PRINT_HIGH("get_parameter: color-format=%x @ index=%d", portFmt->eColorFormat, portFmt->nIndex);
}
else
{
@@ -3573,6 +3576,7 @@
EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
if(enableNativeBuffers) {
m_enable_android_native_buffers = enableNativeBuffers->enable;
+ client_buffers.enable_native_buffers(m_enable_android_native_buffers);
}
}
break;
@@ -4403,8 +4407,9 @@
}
if(port == OMX_CORE_INPUT_PORT_INDEX)
error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
- else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
- error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
+ else if(port == OMX_CORE_OUTPUT_PORT_INDEX) {
+ error = client_buffers.use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
+ }
else
{
DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
@@ -5087,7 +5092,7 @@
drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
&drv_ctx.op_buf_ion_info[i].ion_alloc_data,
- &drv_ctx.op_buf_ion_info[i].fd_ion_data, ION_FLAG_CACHED);
+ &drv_ctx.op_buf_ion_info[i].fd_ion_data, 0);
if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
return OMX_ErrorInsufficientResources;
}
@@ -7994,13 +7999,9 @@
}
portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
- portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
- portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
- if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
- (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
- portDefn->format.video.nStride = drv_ctx.video_resolution.frame_width;
- portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
- }
+ portDefn->format.video.nStride = client_buffers.get_output_stride();
+ portDefn->format.video.nSliceHeight = client_buffers.get_output_scanlines();
+
DEBUG_PRINT_LOW("update_portdef Width = %d Height = %d Stride = %u"
"SliceHeight = %u \n", portDefn->format.video.nFrameHeight,
portDefn->format.video.nFrameWidth,
@@ -9046,6 +9047,7 @@
omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
{
enabled = false;
+ m_native_buffers_enabled = false;
omx = NULL;
init_members();
ColorFormat = OMX_COLOR_FormatMax;
@@ -9095,8 +9097,8 @@
pthread_mutex_lock(&omx->c_lock);
c2d.close();
status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
- omx->drv_ctx.video_resolution.frame_width,
- YCbCr420Tile, dest_format);
+ omx->drv_ctx.video_resolution.frame_width,
+ YCbCr420Tile, dest_format);
if (status) {
status = c2d.get_buffer_size(C2D_INPUT,src_size);
if (status)
@@ -9200,6 +9202,21 @@
status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
bufadd->pBuffer, bufadd->pBuffer, pmem_fd[index],
pmem_baseaddress[index], pmem_baseaddress[index]);
+// DEBUG: dump converted output
+#if 0
+ {
+ int w = get_output_stride();
+ int h = get_output_scanlines();
+ char fileName[128] = {0};
+ sprintf(fileName,"/data/misc/media/out_%d_%d.yuv",w,h);
+ FILE* fp = fopen(fileName,"ab");
+ if (fp) {
+ ALOGI("c2d: dumped: %s",fileName);
+ fwrite(pmem_baseaddress[index], (w * h * 3)/2, 1, fp);
+ fclose(fp);
+ }
+ }
+#endif
pthread_mutex_unlock(&omx->c_lock);
m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
if (!status){
@@ -9252,6 +9269,31 @@
buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
return true;
}
+
+OMX_U32 omx_vdec::allocate_color_convert_buf::get_output_stride() {
+ // If Converting to Planar/SemiPlanar in bytebuffer mode, stride/slice-height
+ // are not aligned per hardware restrictions.
+ if (enabled &&
+ (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
+ ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
+ return ALIGN(omx->drv_ctx.video_resolution.frame_width, ALIGN16);
+ } else {
+ return omx->drv_ctx.video_resolution.stride;
+ }
+}
+
+OMX_U32 omx_vdec::allocate_color_convert_buf::get_output_scanlines() {
+ // If Converting to Planar/SemiPlanar in bytebuffer mode, stride/slice-height
+ // are not aligned per hardware restrictions.
+ if (enabled &&
+ (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
+ ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
+ return omx->drv_ctx.video_resolution.frame_height;
+ } else {
+ return omx->drv_ctx.video_resolution.scan_lines;
+ }
+}
+
OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
OMX_BUFFERHEADERTYPE *bufhdr) {
unsigned int index = 0;
@@ -9269,12 +9311,33 @@
DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
return OMX_ErrorBadParameter;
}
- if (pmem_fd[index] > 0) {
- munmap(pmem_baseaddress[index], buffer_size_req);
- close(pmem_fd[index]);
+ if (m_native_buffers_enabled) {
+ // unmap client's fd
+ if (pmem_fd[index] > 0 && pmem_baseaddress[index]) {
+ munmap(pmem_baseaddress[index], buffer_size_req);
+ pmem_baseaddress[index] = 0;
+ }
+ // free from internal set
+ // Do this explicitly as omx->free_output_buffer() does not free
+ // the memory when native-buffers are enabled
+ if (omx->drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
+ DEBUG_PRINT_LOW("free_buffer(conversion): free ion mem[%d] fd=%d size=%d",
+ index, omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
+ omx->drv_ctx.ptr_outputbuffer[index].mmaped_size);
+ munmap (omx->drv_ctx.ptr_outputbuffer[index].bufferaddr,
+ omx->drv_ctx.ptr_outputbuffer[index].mmaped_size);
+ omx->free_ion_memory(&(omx->drv_ctx.op_buf_ion_info[index]));
+ close (omx->drv_ctx.ptr_outputbuffer[index].pmem_fd);
+ omx->drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
+ }
+ } else {
+ if (pmem_fd[index] > 0) {
+ munmap(pmem_baseaddress[index], buffer_size_req);
+ close(pmem_fd[index]);
+ }
+ pmem_fd[index] = -1;
+ omx->free_ion_memory(&op_buf_ion_info[index]);
}
- pmem_fd[index] = -1;
- omx->free_ion_memory(&op_buf_ion_info[index]);
m_heap_ptr[index].video_heap_ptr = NULL;
if (allocated_count > 0)
allocated_count--;
@@ -9329,7 +9392,7 @@
op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
buffer_size_req,buffer_alignment_req,
&op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
- ION_FLAG_CACHED);
+ 0);
pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
if (op_buf_ion_info[i].ion_device_fd < 0) {
@@ -9370,6 +9433,85 @@
return eRet;
}
+OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::use_output_buffer(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE **bufferHdr, OMX_U32 port, OMX_PTR appData,
+ OMX_U32 bytes, OMX_U8 *buffer)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ const char *func = "use_buf(conversion)";
+
+ if (!enabled) {
+ return omx->use_output_buffer(hComp, bufferHdr, port, appData, bytes, buffer);
+ }
+ // assert native-buffer-mode is enabled
+ if (!m_native_buffers_enabled) {
+ DEBUG_PRINT_ERROR("%s: use_buffer called in non-surface mode", func);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ if (omx->is_component_secure()) {
+ DEBUG_PRINT_ERROR("%s: Cannot color-convert secure buffers", func);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ if (!bufferHdr || bytes > buffer_size_req) {
+ DEBUG_PRINT_ERROR("%s: Invalid params hdr=%p requested-size=%d passed-size=%d",
+ func, bufferHdr, buffer_size_req, bytes);
+ return OMX_ErrorBadParameter;
+ }
+ if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
+ DEBUG_PRINT_ERROR("%s: all buffers (%d) already allocated", func, allocated_count);
+ return OMX_ErrorInsufficientResources;
+ }
+
+ // Allocate pixel buffer for the decoder
+ OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
+ eRet = omx->allocate_output_buffer(hComp, &temp_bufferHdr,
+ port, appData, omx->drv_ctx.op_buf.buffer_size);
+ if (eRet != OMX_ErrorNone || !temp_bufferHdr){
+ DEBUG_PRINT_ERROR("%s: decoder's o/p allocation failed", func);
+ return eRet;
+ }
+ if ((temp_bufferHdr - omx->m_out_mem_ptr) >= omx->drv_ctx.op_buf.actualcount) {
+ DEBUG_PRINT_ERROR("%s: Invalid header index %d",
+ func, (temp_bufferHdr - omx->m_out_mem_ptr));
+ return OMX_ErrorUndefined;
+ }
+ unsigned int i = allocated_count;
+ private_handle_t *handle = (private_handle_t *)buffer;
+
+ pmem_fd[i] = handle->fd;
+ pmem_baseaddress[i] = (OMX_U8*)mmap(0, handle->size,
+ PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
+ if (pmem_baseaddress[i] == MAP_FAILED) {
+ DEBUG_PRINT_ERROR("%s: Failed to map native handle fd=%d size=%d",
+ func, handle->fd, handle->size);
+ return OMX_ErrorInsufficientResources;
+ }
+ m_heap_ptr[i].video_heap_ptr = NULL; //not used
+ m_pmem_info_client[i].pmem_fd = handle->fd;
+ m_pmem_info_client[i].offset = 0;
+ m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
+ m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
+ m_platform_list_client[i].nEntries = 1;
+ m_platform_list_client[i].entryList = &m_platform_entry_client[i];
+ m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
+ m_out_mem_ptr_client[i].nAllocLen = handle->size;
+ m_out_mem_ptr_client[i].nFilledLen = 0;
+ m_out_mem_ptr_client[i].nFlags = 0;
+ m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
+ m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
+ m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
+ m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
+
+ m_out_mem_ptr_client[i].pBuffer = buffer;
+ m_out_mem_ptr_client[i].pAppPrivate = appData;
+
+ *bufferHdr = &m_out_mem_ptr_client[i];
+ DEBUG_PRINT_LOW("%s: allocated header[%d]=%p for native handle[fd=%d size=%d]",
+ func, i, *bufferHdr, handle->fd, handle->size);
+ allocated_count++;
+ return eRet;
+}
+
bool omx_vdec::is_component_secure()
{
return secure_mode;
diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
index 3ca6d64..59fd836 100755
--- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
+++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
@@ -1036,30 +1036,18 @@
perf_control m_perf_control;
volatile int32_t m_queued_codec_config_count;
- static OMX_COLOR_FORMATTYPE getPreferredColorFormatNonSurfaceMode(OMX_U32 index) {
- //On Android, we default to standard YUV formats for non-surface use-cases
- //where apps prefer known color formats.
- OMX_COLOR_FORMATTYPE formatsNonSurfaceMode[] = {
- [0] = OMX_COLOR_FormatYUV420SemiPlanar,
- [1] = OMX_COLOR_FormatYUV420Planar,
- [2] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
+ static OMX_COLOR_FORMATTYPE getColorFormatAt(OMX_U32 index) {
+ OMX_COLOR_FORMATTYPE formats[] = {
+ [0] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
+ [1] = OMX_COLOR_FormatYUV420SemiPlanar,
+ [2] = OMX_COLOR_FormatYUV420Planar,
[3] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView,
};
- return (index < sizeof(formatsNonSurfaceMode) / sizeof(OMX_COLOR_FORMATTYPE)) ?
- formatsNonSurfaceMode[index] : OMX_COLOR_FormatMax;
+ return (index < sizeof(formats) / sizeof(OMX_COLOR_FORMATTYPE)) ?
+ formats[index] : OMX_COLOR_FormatMax;
}
- static OMX_COLOR_FORMATTYPE getPreferredColorFormatDefaultMode(OMX_U32 index) {
- //for surface mode (normal playback), advertise native/accelerated formats first
- OMX_COLOR_FORMATTYPE formatsDefault[] = {
- [0] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
- [1] = OMX_COLOR_FormatYUV420Planar,
- [2] = OMX_COLOR_FormatYUV420SemiPlanar,
- [3] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView,
- };
- return (index < sizeof(formatsDefault) / sizeof(OMX_COLOR_FORMATTYPE)) ?
- formatsDefault[index] : OMX_COLOR_FormatMax;
- }
+ static OMX_ERRORTYPE describeColorFormat(DescribeColorFormatParams *params);
};
#ifdef _MSM8974_
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 f5f0898..69fe2c4 100755
--- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp
+++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp
@@ -2822,17 +2822,7 @@
}
} else if (1 == portFmt->nPortIndex) {
portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
-
- // Distinguish non-surface mode from normal playback use-case based on
- // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
- // For non-android, use the default list
- bool useNonSurfaceMode = false;
-#if _ANDROID_
- useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
-#endif
- portFmt->eColorFormat = useNonSurfaceMode ?
- getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
- getPreferredColorFormatDefaultMode(portFmt->nIndex);
+ portFmt->eColorFormat = getColorFormatAt(portFmt->nIndex);
if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
eRet = OMX_ErrorNoMore;
@@ -2971,7 +2961,11 @@
}
break;
#endif
-
+ case OMX_QcomIndexFlexibleYUVDescription: {
+ DEBUG_PRINT_LOW("get_parameter: describeColorFormat");
+ eRet = describeColorFormat((DescribeColorFormatParams *)paramData);
+ break;
+ }
default: {
DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
eRet =OMX_ErrorUnsupportedIndex;
@@ -3613,13 +3607,6 @@
if (enableNativeBuffers) {
m_enable_android_native_buffers = enableNativeBuffers->enable;
}
- if (m_enable_android_native_buffers) {
- // Use the most-preferred-native-color-format as surface-mode is hinted here
- if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
- DEBUG_PRINT_ERROR("Failed to set native color format!");
- eRet = OMX_ErrorUnsupportedSetting;
- }
- }
}
break;
case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
@@ -4159,6 +4146,9 @@
*indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
}
#endif
+ else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription;
+ }
else {
DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
return OMX_ErrorNotImplemented;
@@ -10093,3 +10083,70 @@
}
}
}
+
+
+//static
+OMX_ERRORTYPE omx_vdec::describeColorFormat(DescribeColorFormatParams *params) {
+ if (params == NULL) {
+ DEBUG_PRINT_ERROR("describeColorFormat: invalid params");
+ return OMX_ErrorBadParameter;
+ }
+
+ MediaImage *img = &(params->sMediaImage);
+ switch(params->eColorFormat) {
+ case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
+ {
+ img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
+ img->mNumPlanes = 3;
+ // mWidth and mHeight represent the W x H of the largest plane
+ // In our case, this happens to be the Stride x Scanlines of Y plane
+ img->mWidth = params->nFrameWidth;
+ img->mHeight = params->nFrameHeight;
+ size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
+ size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight);
+ img->mBitDepth = 8;
+ //Plane 0 (Y)
+ img->mPlane[MediaImage::Y].mOffset = 0;
+ img->mPlane[MediaImage::Y].mColInc = 1;
+ img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride
+ img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
+ img->mPlane[MediaImage::Y].mVertSubsampling = 1;
+ //Plane 1 (U)
+ img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight;
+ img->mPlane[MediaImage::U].mColInc = 2; //interleaved UV
+ img->mPlane[MediaImage::U].mRowInc =
+ VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
+ img->mPlane[MediaImage::U].mHorizSubsampling = 2;
+ img->mPlane[MediaImage::U].mVertSubsampling = 2;
+ //Plane 2 (V)
+ img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1;
+ img->mPlane[MediaImage::V].mColInc = 2; //interleaved UV
+ img->mPlane[MediaImage::V].mRowInc =
+ VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
+ img->mPlane[MediaImage::V].mHorizSubsampling = 2;
+ img->mPlane[MediaImage::V].mVertSubsampling = 2;
+ break;
+ }
+
+ case OMX_COLOR_FormatYUV420Planar:
+ case OMX_COLOR_FormatYUV420SemiPlanar:
+ // We need not describe the standard OMX linear formats as these are
+ // understood by client. Fail this deliberately to let client fill-in
+ return OMX_ErrorUnsupportedSetting;
+
+ default:
+ // Rest all formats which are non-linear cannot be described
+ DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat);
+ img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
+ return OMX_ErrorNone;
+ };
+
+ DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat);
+ DEBUG_PRINT_LOW(" FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight);
+ DEBUG_PRINT_LOW(" YWidth x YHeight : %d x %d", img->mWidth, img->mHeight);
+ for (size_t i = 0; i < img->mNumPlanes; ++i) {
+ DEBUG_PRINT_LOW(" Plane[%d] : offset=%d / xStep=%d / yStep = %d",
+ i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc);
+ }
+ return OMX_ErrorNone;
+}