diff options
Diffstat (limited to 'mm-video-v4l2')
-rwxr-xr-x | mm-video-v4l2/vidc/vdec/Android.mk | 5 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/vdec/inc/omx_vdec.h | 9 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc.h | 1 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc_swvdec.h | 50 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp | 55 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc_swvdec.cpp | 631 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp | 75 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/vdec/test/omx_vdec_test.cpp | 92 |
8 files changed, 625 insertions, 293 deletions
diff --git a/mm-video-v4l2/vidc/vdec/Android.mk b/mm-video-v4l2/vidc/vdec/Android.mk index 3acef60e..00d22ea3 100755 --- a/mm-video-v4l2/vidc/vdec/Android.mk +++ b/mm-video-v4l2/vidc/vdec/Android.mk @@ -116,6 +116,11 @@ libOmxVdec-def += -DMETA_DATA_MODE_SUPPORTED libmm-vdec-inc += hardware/qcom/media/libstagefrighthw endif +ifneq ($(call is-platform-sdk-version-at-least,19),true) +libOmxVdec-def += -DMETADATA_FOR_DYNAMIC_MODE +libmm-vdec-inc += hardware/qcom/media/libstagefrighthw +endif + LOCAL_MODULE := libOmxVdec LOCAL_MODULE_TAGS := optional LOCAL_CFLAGS := $(libOmxVdec-def) diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h index 00fa8b53..7ebd02f1 100644 --- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h +++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h @@ -278,14 +278,12 @@ struct debug_cap { FILE *outfile; }; -#ifdef META_DATA_MODE_SUPPORTED struct dynamic_buf_list { OMX_U32 fd; OMX_U32 dup_fd; OMX_U32 offset; OMX_U32 ref_count; }; -#endif // OMX video decoder class class omx_vdec: public qc_omx_component @@ -424,10 +422,8 @@ class omx_vdec: public qc_omx_component pthread_t msg_thread_id; pthread_t async_thread_id; bool is_component_secure(); -#ifdef META_DATA_MODE_SUPPORTED void buf_ref_add(OMX_U32 fd, OMX_U32 offset); void buf_ref_remove(OMX_U32 fd, OMX_U32 offset); -#endif private: // Bit Positions @@ -658,6 +654,8 @@ class omx_vdec: public qc_omx_component void append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra); void append_extn_extradata(OMX_OTHER_EXTRADATATYPE *extra, OMX_OTHER_EXTRADATATYPE *p_extn); void append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra, OMX_OTHER_EXTRADATATYPE *p_user); + void append_concealmb_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_OTHER_EXTRADATATYPE *p_concealmb, OMX_U8 *conceal_mb_data); void insert_demux_addr_offset(OMX_U32 address_offset); void extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr); OMX_ERRORTYPE handle_demux_data(OMX_BUFFERHEADERTYPE *buf_hdr); @@ -893,6 +891,7 @@ class omx_vdec: public qc_omx_component bool external_meta_buffer; bool external_meta_buffer_iommu; OMX_QCOM_EXTRADATA_FRAMEINFO *m_extradata; + OMX_OTHER_EXTRADATATYPE *m_other_extradata; bool codec_config_flag; #ifdef _MSM8974_ int capture_capability; @@ -911,11 +910,9 @@ class omx_vdec: public qc_omx_component OMX_VIDEO_PARAM_PROFILELEVELTYPE m_profile_lvl; OMX_U32 m_profile; -#ifdef META_DATA_MODE_SUPPORTED //variables to handle dynamic buffer mode bool dynamic_buf_mode; struct dynamic_buf_list *out_dynamic_list; -#endif unsigned int m_fill_output_msg; bool client_set_fps; diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc.h index 8907a560..79f779ac 100644 --- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc.h +++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc.h @@ -846,6 +846,7 @@ class omx_vdec: public qc_omx_component bool external_meta_buffer; bool external_meta_buffer_iommu; OMX_QCOM_EXTRADATA_FRAMEINFO *m_extradata; + OMX_OTHER_EXTRADATATYPE *m_other_extradata; bool codec_config_flag; #ifdef _MSM8974_ int capture_capability; diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc_swvdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc_swvdec.h index df4057ea..5e1021f5 100644 --- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc_swvdec.h +++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc_swvdec.h @@ -109,6 +109,12 @@ extern "C"{ #include "extra_data_handler.h" #include "ts_parser.h" #include "vidc_color_converter.h" +#include "vidc_debug.h" +#ifdef _ANDROID_ +#include <cutils/properties.h> +#else +#define PROPERTY_VALUE_MAX 92 +#endif extern "C" { OMX_API void * get_omx_component_factory_fn(void); } @@ -280,6 +286,26 @@ struct video_driver_context class DivXDrmDecrypt; #endif //_ANDROID_ +struct video_decoder_capability { + unsigned int min_width; + unsigned int max_width; + unsigned int min_height; + unsigned int max_height; +}; + +struct debug_cap { + bool in_buffer_log; + bool out_buffer_log; + bool im_buffer_log; + char infile_name[PROPERTY_VALUE_MAX + 36]; + char outfile_name[PROPERTY_VALUE_MAX + 36]; + char imbfile_name[PROPERTY_VALUE_MAX + 36]; + char log_loc[PROPERTY_VALUE_MAX]; + FILE *infile; + FILE *outfile; + FILE *imbfile; +}; + // OMX video decoder class class omx_vdec: public qc_omx_component { @@ -409,7 +435,8 @@ public: #ifdef _MSM8974_ OMX_ERRORTYPE allocate_extradata(); void free_extradata(); - void update_resolution(int width, int height); + int update_resolution(int width, int height, int stride, int scan_lines); + OMX_ERRORTYPE is_video_session_supported(); #endif int m_pipe_in; int m_pipe_out; @@ -495,7 +522,7 @@ private: OMX_COMPONENT_GENERATE_FBD_DSP = 0x1A, OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH_DSP = 0x1C, OMX_COMPONENT_GENERATE_STOP_DONE_SWVDEC = 0x1D, - + OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING = 0x1E, }; enum vc1_profile_type @@ -746,12 +773,23 @@ private: { if (m_cb.EventHandler && !m_error_propogated) { - ALOGE("\nERROR: Sending OMX_EventError to Client"); + DEBUG_PRINT_ERROR("\nERROR: Sending OMX_EventError to Client"); m_error_propogated = true; m_cb.EventHandler(&m_cmp,m_app_data, OMX_EventError,OMX_ErrorHardware,0,NULL); } } + + inline void omx_report_unsupported_setting () + { + if (m_cb.EventHandler && !m_error_propogated) + { + DEBUG_PRINT_ERROR("ERROR: Sending OMX_ErrorUnsupportedSetting to Client"); + m_error_propogated = true; + m_cb.EventHandler(&m_cmp,m_app_data, + OMX_EventError,OMX_ErrorUnsupportedSetting,0,NULL); + } + } #ifdef _ANDROID_ OMX_ERRORTYPE createDivxDrmContext(); #endif //_ANDROID_ @@ -958,6 +996,7 @@ private: int output_capability; bool streaming[MAX_PORT]; OMX_CONFIG_RECTTYPE rectangle; + int prev_n_filled_len; #endif bool m_power_hinted; OMX_ERRORTYPE power_module_register(); @@ -1016,6 +1055,11 @@ private: allocate_color_convert_buf client_buffers; #endif HEVC_Utils mHEVCutils; + struct video_decoder_capability m_decoder_capability; + struct debug_cap m_debug; + int log_input_buffers(const char *, int); + int log_output_buffers(OMX_BUFFERHEADERTYPE *); + int log_im_buffer(OMX_BUFFERHEADERTYPE * buffer); }; #ifdef _MSM8974_ diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp index 4b04c54d..583d52bd 100644 --- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp +++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp @@ -537,6 +537,7 @@ omx_vdec::omx_vdec(): m_error_propogated(false), m_display_id(NULL), h264_parser(NULL), client_extradata(0), + m_other_extradata(NULL), #ifdef _ANDROID_ m_enable_android_native_buffers(OMX_FALSE), m_use_android_native_buffers(OMX_FALSE), @@ -1539,7 +1540,7 @@ OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) m_state = OMX_StateLoaded; #ifdef DEFAULT_EXTRADATA - if (eRet == OMX_ErrorNone && !secure_mode) + if (eRet == OMX_ErrorNone) enable_extradata(DEFAULT_EXTRADATA, true, true); #endif eRet=get_buffer_req(&drv_ctx.ip_buf); @@ -3610,6 +3611,13 @@ OMX_ERRORTYPE omx_vdec::allocate_extradata() memset(drv_ctx.extradata_info.uaddr, 0, drv_ctx.extradata_info.size); } #endif + if (!m_other_extradata) { + m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.size); + if (!m_other_extradata) { + DEBUG_PRINT_ERROR("Failed to alloc memory\n"); + return OMX_ErrorInsufficientResources; + } + } return OMX_ErrorNone; } @@ -3623,6 +3631,10 @@ void omx_vdec::free_extradata() } memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); #endif + if (m_other_extradata) { + free(m_other_extradata); + m_other_extradata = NULL; + } } OMX_ERRORTYPE omx_vdec::use_output_buffer( @@ -3799,6 +3811,9 @@ OMX_ERRORTYPE omx_vdec::use_output_buffer( } m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd; + m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len; + m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size; + m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr; *bufferHdr = (m_out_mem_ptr + i ); if (secure_mode) @@ -4556,6 +4571,9 @@ OMX_ERRORTYPE omx_vdec::allocate_output_buffer( drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i; drv_ctx.ptr_outputbuffer[i].bufferaddr = pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i); + m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len; + m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size; + m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr; DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p", pmem_fd, drv_ctx.ptr_outputbuffer[i].offset, @@ -6958,7 +6976,6 @@ int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, ion_buf_info.fd_ion_data = *fd_data; free_ion_memory(&ion_buf_info); fd_data->fd =-1; - close(fd); fd = -ENOMEM; } @@ -7592,11 +7609,19 @@ void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) if (!drv_ctx.extradata_info.uaddr) { return; } - p_extra = (OMX_OTHER_EXTRADATATYPE *) - ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3)); + + if (!secure_mode) + p_extra = (OMX_OTHER_EXTRADATATYPE *) + ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3)); + else + p_extra = m_other_extradata; + char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size; - if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen)) + + if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) { p_extra = NULL; + return; + } OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata; if (data) { while ((consumed_len < drv_ctx.extradata_info.buffer_size) @@ -7621,7 +7646,7 @@ void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, PP_PARAM_INTERLACED, (void*)&enable); } - if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) { + if (client_extradata & OMX_INTERLACE_EXTRADATA) { append_interlace_extradata(p_extra, payload->format); p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); } @@ -7670,17 +7695,25 @@ void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) consumed_len += data->nSize; data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize); } - if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) { + if (client_extradata & OMX_FRAMEINFO_EXTRADATA) { p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; append_frame_info_extradata(p_extra, - num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate, - panscan_payload,&((struct vdec_output_frameinfo *) - p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info); + num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate, + panscan_payload,&((struct vdec_output_frameinfo *) + p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); } } unrecognized_extradata: - if (!secure_mode && client_extradata) + if (client_extradata) append_terminator_extradata(p_extra); + if (secure_mode) { + memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size); + ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->metadata_info.metabufaddr = + (void *)p_extradata; + ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->metadata_info.size = + drv_ctx.extradata_info.buffer_size; + } return; } diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc_swvdec.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc_swvdec.cpp index fcabf0e4..73ac9985 100644 --- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc_swvdec.cpp +++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc_swvdec.cpp @@ -60,10 +60,6 @@ This module contains the implementation of the OpenMAX core & component. #undef USE_EGL_IMAGE_GPU #endif -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) -#include <gralloc_priv.h> -#endif - #include <qdMetaData.h> #ifdef _ANDROID_ @@ -77,16 +73,8 @@ This module contains the implementation of the OpenMAX core & component. #define EGL_BUFFER_OFFSET_QCOM 0x4F01 #endif -#ifdef INPUT_BUFFER_LOG -#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0" -#define INPUT_BUFFER_FILE_NAME_LEN 30 -FILE *inputBufferFile1; -char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0"; -#endif -#ifdef OUTPUT_BUFFER_LOG -FILE *outputBufferFile1; -char outputfilename [] = "/data/output.yuv"; -#endif +#define BUFFER_LOG_LOC "/data/misc/media" + #ifdef OUTPUT_EXTRADATA_LOG FILE *outputExtradataFile; char ouputextradatafilename [] = "/data/extradata"; @@ -205,7 +193,7 @@ void* async_message_thread (void *input) struct vdec_msginfo vdec_msg; vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED; vdec_msg.status_code=VDEC_S_SUCCESS; - DEBUG_PRINT_HIGH("VIDC Port Reconfig recieved"); + DEBUG_PRINT_HIGH("VIDC Port Reconfig recieved insufficient"); if (omx->async_message_process(input,&vdec_msg) < 0) { DEBUG_PRINT_HIGH("async_message_thread Exited"); break; @@ -223,14 +211,14 @@ void* async_message_thread (void *input) struct vdec_msginfo vdec_msg; vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE; vdec_msg.status_code=VDEC_S_SUCCESS; - DEBUG_PRINT_HIGH("VIDC input Flush Done Recieved"); + DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved "); if (omx->async_message_process(input,&vdec_msg) < 0) { DEBUG_PRINT_HIGH("async_message_thread Exited"); break; } vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE; vdec_msg.status_code=VDEC_S_SUCCESS; - DEBUG_PRINT_HIGH("VIDC output Flush Done Recieved"); + DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved "); if (omx->async_message_process(input,&vdec_msg) < 0) { DEBUG_PRINT_HIGH("async_message_thread Exited"); break; @@ -603,6 +591,7 @@ omx_vdec::omx_vdec(): dec_time.start(); proc_frms = latency = 0; } + prev_n_filled_len = 0; property_value[0] = '\0'; property_get("vidc.dec.debug.ts", property_value, "0"); m_debug_timestamp = atoi(property_value); @@ -612,12 +601,29 @@ omx_vdec::omx_vdec(): time_stamp_dts.set_timestamp_reorder_mode(true); time_stamp_dts.enable_debug_print(true); } - + memset(&m_debug, 0, sizeof(m_debug)); property_value[0] = '\0'; property_get("vidc.dec.debug.concealedmb", property_value, "0"); m_debug_concealedmb = atoi(property_value); DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb); + property_value[0] = '\0'; + property_get("vidc.dec.log.in", property_value, "0"); + m_debug.in_buffer_log = atoi(property_value); + + property_value[0] = '\0'; + property_get("vidc.dec.log.out", property_value, "0"); + m_debug.out_buffer_log = atoi(property_value); + + property_value[0] = '\0'; + property_get("vidc.dec.log.imb", property_value, "0"); + m_debug.im_buffer_log = atoi(property_value); + + sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC); + property_value[0] = '\0'; + property_get("vidc.log.loc", property_value, ""); + if (*property_value) + strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX); #endif memset(&m_cmp,0,sizeof(m_cmp)); memset(&m_cb,0,sizeof(m_cb)); @@ -626,6 +632,10 @@ omx_vdec::omx_vdec(): memset (m_hwdevice_name,0,sizeof(m_hwdevice_name)); memset(m_demux_offsets, 0, sizeof(m_demux_offsets) ); m_demux_entries = 0; + msg_thread_id = 0; + async_thread_id = 0; + msg_thread_created = false; + async_thread_created = false; #ifdef _ANDROID_ICS_ memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); #endif @@ -738,26 +748,38 @@ omx_vdec::~omx_vdec() m_pipe_in = -1; m_pipe_out = -1; DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit"); - pthread_join(msg_thread_id,NULL); + if (msg_thread_created) + pthread_join(msg_thread_id,NULL); if (!m_pSwVdec || m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY) { - DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit"); + DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit driver id %d", drv_ctx.video_driver_fd); dec.cmd = V4L2_DEC_CMD_STOP; - if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) + if (drv_ctx.video_driver_fd >=0 ) { - DEBUG_PRINT_ERROR("STOP Command failed"); + DEBUG_PRINT_HIGH("Stop decoder driver instance"); + if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) + { + DEBUG_PRINT_ERROR("STOP Command failed"); + } } - pthread_join(async_thread_id,NULL); + + if (async_thread_created) + pthread_join(async_thread_id,NULL); + unsubscribe_to_events(drv_ctx.video_driver_fd); close(drv_ctx.video_driver_fd); } - if (m_pSwVdec && SWVDEC_S_SUCCESS != SwVdec_Stop(m_pSwVdec)) + if (m_pSwVdec) { - DEBUG_PRINT_ERROR("SwVdec_Stop Command failed in vdec destructor"); - SwVdec_DeInit(m_pSwVdec); - m_pSwVdec = NULL; + DEBUG_PRINT_HIGH("SwVdec_Stop"); + if (SWVDEC_S_SUCCESS != SwVdec_Stop(m_pSwVdec)) + { + DEBUG_PRINT_ERROR("SwVdec_Stop Command failed in vdec destructor"); + SwVdec_DeInit(m_pSwVdec); + m_pSwVdec = NULL; + } } pthread_mutex_destroy(&m_lock); @@ -771,7 +793,8 @@ omx_vdec::~omx_vdec() DEBUG_PRINT_HIGH("Exit OMX vdec Destructor"); } -int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) { +int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) +{ struct v4l2_requestbuffers bufreq; int rc = 0; if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT){ @@ -779,6 +802,11 @@ int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) { bufreq.count = 0; bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); + } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) { + bufreq.memory = V4L2_MEMORY_USERPTR; + bufreq.count = 0; + bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); } return rc; } @@ -1054,7 +1082,6 @@ void omx_vdec::process_event_cb(void *ctxt, unsigned char id) break; case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: - DEBUG_PRINT_HIGH("i"); if (!pThis->input_flush_progress) { DEBUG_PRINT_ERROR("WARNING: Unexpected INPUT_FLUSH from driver"); @@ -1160,6 +1187,9 @@ void omx_vdec::process_event_cb(void *ctxt, unsigned char id) OMX_COMPONENT_GENERATE_EVENT); BITMASK_CLEAR (&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); + BITMASK_CLEAR (&pThis->m_flags, + OMX_COMPONENT_OUTPUT_DISABLE_PENDING); + } } @@ -1416,6 +1446,12 @@ void omx_vdec::process_event_cb(void *ctxt, unsigned char id) DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR"); pThis->omx_report_error (); break; + + case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING: + DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING"); + pThis->omx_report_unsupported_setting(); + break; + case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG: { DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG"); @@ -1503,16 +1539,121 @@ void omx_vdec::process_event_cb(void *ctxt, unsigned char id) } -void omx_vdec::update_resolution(int width, int height) +int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines) { + int format_changed = 0; + if ((height != (int)drv_ctx.video_resolution.frame_height) || + (width != (int)drv_ctx.video_resolution.frame_width)) { + DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)", + width, drv_ctx.video_resolution.frame_width, + height,drv_ctx.video_resolution.frame_height); + format_changed = 1; + } drv_ctx.video_resolution.frame_height = height; drv_ctx.video_resolution.frame_width = width; - drv_ctx.video_resolution.scan_lines = height; - drv_ctx.video_resolution.stride = width; + drv_ctx.video_resolution.scan_lines = scan_lines; + drv_ctx.video_resolution.stride = stride; rectangle.nLeft = 0; rectangle.nTop = 0; rectangle.nWidth = drv_ctx.video_resolution.frame_width; rectangle.nHeight = drv_ctx.video_resolution.frame_height; + return format_changed; +} + +OMX_ERRORTYPE omx_vdec::is_video_session_supported() +{ + if ((drv_ctx.video_resolution.frame_width * drv_ctx.video_resolution.frame_height > + m_decoder_capability.max_width * m_decoder_capability.max_height) || + (drv_ctx.video_resolution.frame_width* drv_ctx.video_resolution.frame_height < + m_decoder_capability.min_width * m_decoder_capability.min_height)) + { + DEBUG_PRINT_ERROR( + "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)", + drv_ctx.video_resolution.frame_width, + drv_ctx.video_resolution.frame_height, + m_decoder_capability.min_width, + m_decoder_capability.min_height, + m_decoder_capability.max_width, + m_decoder_capability.max_height); + return OMX_ErrorUnsupportedSetting; + } + DEBUG_PRINT_HIGH("video session supported"); + return OMX_ErrorNone; +} + +int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len) +{ + if (m_debug.in_buffer_log && !m_debug.infile) { + if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE) || + !strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.hevchybrid", OMX_MAX_STRINGNAME_SIZE) ) { + sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.hevc", + m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); + } + m_debug.infile = fopen (m_debug.infile_name, "ab"); + if (!m_debug.infile) { + DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name); + m_debug.infile_name[0] = '\0'; + return -1; + } + } + if (m_debug.infile && buffer_addr && buffer_len) { + fwrite(buffer_addr, buffer_len, 1, m_debug.infile); + } + return 0; +} + +int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) +{ + if (m_debug.out_buffer_log && !m_debug.outfile) { + sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv", + m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); + m_debug.outfile = fopen (m_debug.outfile_name, "ab"); + if (!m_debug.outfile) { + DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc); + m_debug.outfile_name[0] = '\0'; + return -1; + } + } + if (m_debug.outfile && buffer && buffer->nFilledLen) { + int buf_index = buffer - m_out_mem_ptr; + int stride = drv_ctx.video_resolution.stride; + int scanlines = drv_ctx.video_resolution.scan_lines; + char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr; + unsigned i; + int bytes_written = 0; + for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) { + bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile); + temp += stride; + } + temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines; + int stride_c = stride; + for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) { + bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile); + temp += stride_c; + } + } + return 0; +} + +int omx_vdec::log_im_buffer(OMX_BUFFERHEADERTYPE * buffer) +{ + if (m_debug.im_buffer_log && !m_debug.imbfile) { + sprintf(m_debug.imbfile_name, "%s/imb_%d_%d_%p.bin", + m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); + m_debug.imbfile = fopen (m_debug.imbfile_name, "ab"); + if (!m_debug.imbfile) { + DEBUG_PRINT_HIGH("Failed to open intermediate file: %s for logging", m_debug.log_loc); + m_debug.imbfile_name[0] = '\0'; + return -1; + } + } + + if (buffer && buffer->nFilledLen) + { + fwrite(&buffer->nFilledLen, sizeof(buffer->nFilledLen), 1, m_debug.imbfile); + fwrite(buffer->pBuffer, sizeof(uint8), buffer->nFilledLen, m_debug.imbfile); + } + return 0; } /* ====================================================================== @@ -1541,11 +1682,17 @@ OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) struct v4l2_format fmt; struct v4l2_requestbuffers bufreq; struct v4l2_control control; + struct v4l2_frmsizeenum frmsize; unsigned int alignment = 0,buffer_size = 0; int fds[2]; int r,ret=0; bool codec_ambiguous = false; + m_decoder_capability.min_width = 16; + m_decoder_capability.min_height = 16; + m_decoder_capability.max_width = 1920; + m_decoder_capability.max_height = 1080; + // Copy the role information which provides the decoder kind strlcpy(drv_ctx.kind,role,128); strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE); @@ -1563,6 +1710,8 @@ OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) OMX_MAX_STRINGNAME_SIZE)) { DEBUG_PRINT_ERROR("Full DSP mode"); + m_decoder_capability.max_width = 1280; + m_decoder_capability.max_height = 720; m_swvdec_mode = -1; } else { @@ -1570,25 +1719,13 @@ OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) return OMX_ErrorInvalidComponentName; } -#ifdef INPUT_BUFFER_LOG - strcpy(inputfilename, INPUT_BUFFER_FILE_NAME); - strcat(inputfilename, "265"); - inputBufferFile1 = fopen (inputfilename, "ab"); -#endif -#ifdef OUTPUT_BUFFER_LOG - outputBufferFile1 = fopen (outputfilename, "wb"); -#endif -#ifdef OUTPUT_EXTRADATA_LOG - outputExtradataFile = fopen (ouputextradatafilename, "ab"); -#endif - drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC; eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc; codec_type_parse = CODEC_TYPE_HEVC; m_frame_parser.init_start_codes (codec_type_parse); m_frame_parser.init_nal_length(nal_length); - update_resolution(320, 240); + update_resolution(320, 240, 320, 240); drv_ctx.output_format = VDEC_YUV_FORMAT_NV12; OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; @@ -1719,10 +1856,27 @@ OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) if (ret) { /*TODO: How to handle this case */ DEBUG_PRINT_ERROR("Failed to set format on output port"); + return OMX_ErrorInsufficientResources; } - else { - DEBUG_PRINT_HIGH("Set Format was successful"); + DEBUG_PRINT_HIGH("Set Format was successful"); + //Get the hardware capabilities + memset((void *)&frmsize,0,sizeof(frmsize)); + frmsize.index = 0; + frmsize.pixel_format = output_capability; + ret = ioctl(drv_ctx.video_driver_fd, + VIDIOC_ENUM_FRAMESIZES, &frmsize); + if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) { + DEBUG_PRINT_ERROR("Failed to get framesizes"); + return OMX_ErrorHardware; } + + if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) { + m_decoder_capability.min_width = frmsize.stepwise.min_width; + m_decoder_capability.max_width = frmsize.stepwise.max_width; + m_decoder_capability.min_height = frmsize.stepwise.min_height; + m_decoder_capability.max_height = frmsize.stepwise.max_height; + } + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; @@ -1804,7 +1958,7 @@ OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) if (eRet != OMX_ErrorNone && ( (!m_pSwVdec) || (m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY) )) { - DEBUG_PRINT_ERROR("Component Init Failed"); + DEBUG_PRINT_ERROR("Component Init Failed eRet %d m_pSwVdec %p m_swvdec_mode %d", eRet, m_pSwVdec, m_swvdec_mode); } else { @@ -3141,6 +3295,7 @@ OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, } else if(OMX_DirInput == portDefn->eDir) { + bool port_format_changed = false; if((portDefn->format.video.xFramerate >> 16) > 0 && (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) { @@ -3175,12 +3330,17 @@ OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, DEBUG_PRINT_LOW("SetParam IP: WxH(%d x %d)", (int)portDefn->format.video.nFrameWidth, (int)portDefn->format.video.nFrameHeight); + port_format_changed = true; if (portDefn->format.video.nFrameHeight != 0x0 && portDefn->format.video.nFrameWidth != 0x0) { update_resolution(portDefn->format.video.nFrameWidth, + portDefn->format.video.nFrameHeight, + portDefn->format.video.nFrameWidth, portDefn->format.video.nFrameHeight); - + eRet = is_video_session_supported(); + if (eRet) + break; if (!m_pSwVdec || m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY) { fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; @@ -3786,7 +3946,6 @@ OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp, DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d",nal_length); return ret; } - return OMX_ErrorNotImplemented; } @@ -5694,13 +5853,10 @@ OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE h } #endif -#ifdef INPUT_BUFFER_LOG - if (inputBufferFile1) + if (m_debug.in_buffer_log) { - fwrite((const char *)temp_buffer->bufferaddr, - temp_buffer->buffer_len,1,inputBufferFile1); + log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len); } -#endif if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) { @@ -6097,18 +6253,19 @@ OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp) } #endif - DEBUG_PRINT_HIGH("Close the driver instance"); + if (m_debug.infile) { + fclose(m_debug.infile); + m_debug.infile = NULL; + } + if (m_debug.outfile) { + fclose(m_debug.outfile); + m_debug.outfile = NULL; + } + if (m_debug.imbfile) { + fclose(m_debug.imbfile); + m_debug.imbfile = NULL; + } -#ifdef INPUT_BUFFER_LOG - fclose (inputBufferFile1); -#endif -#ifdef OUTPUT_BUFFER_LOG - if (outputBufferFile1) - fclose (outputBufferFile1); -#endif -#ifdef OUTPUT_EXTRADATA_LOG - fclose (outputExtradataFile); -#endif if (m_pSwVdec) { SwVdec_DeInit(m_pSwVdec); @@ -6554,26 +6711,10 @@ OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp, } } -#ifdef OUTPUT_BUFFER_LOG - if (outputBufferFile1 && buffer->nFilledLen) + if (m_debug.out_buffer_log) { - int stride = drv_ctx.video_resolution.stride; - int scanlines = drv_ctx.video_resolution.scan_lines; - char *temp = (char *)buffer->pBuffer; - int i; - int bytes_written = 0; - for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) { - bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1); - temp += stride; - } - temp = (char *)buffer->pBuffer + stride * scanlines; - int stride_c = stride; - for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) { - bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1); - temp += stride_c; - } + log_output_buffers(buffer); } -#endif /* For use buffer we need to copy the data */ if (!output_flush_progress) @@ -6829,7 +6970,13 @@ int omx_vdec::async_message_process (void *context, void* message) omxhdr = NULL; vdec_msg->status_code = VDEC_S_EFATAL; } - + if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) { + DEBUG_PRINT_HIGH("Unsupported input"); + omx->omx_report_error (); + } + if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) { + vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR; + } omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, OMX_COMPONENT_GENERATE_EBD); break; @@ -6844,7 +6991,6 @@ int omx_vdec::async_message_process (void *context, void* message) vdec_msg->msgdata.output_frame.time_stamp); } break; - case VDEC_MSG_RESP_OUTPUT_FLUSHED: case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: { @@ -6873,45 +7019,122 @@ int omx_vdec::async_message_process (void *context, void* message) omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len; omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset; omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp; - omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags; + omxhdr->nFlags = 0; - if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) - { + if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) { omxhdr->nFlags |= OMX_BUFFERFLAG_EOS; //rc = -1; } - if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) - { + if (omxhdr->nFilledLen) { + omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + } + if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) { + omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; + } else { + omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME; + } + if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) { omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; } + if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) { + omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY; + } + if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) && + !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) && + !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) { + omx->time_stamp_dts.remove_time_stamp( + omxhdr->nTimeStamp, + (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) + ?true:false); + omx->post_event ((unsigned)NULL,(unsigned int)omxhdr, + OMX_COMPONENT_GENERATE_FTB); + break; + } + if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) { + omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; + } vdec_msg->msgdata.output_frame.bufferaddr = omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr; + int format_notably_changed = 0; + if (omxhdr->nFilledLen && + (omxhdr->nFilledLen != (unsigned)omx->prev_n_filled_len)) { + if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) || + (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) { + DEBUG_PRINT_HIGH("Height/Width information has changed"); + omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom; + omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right; + format_notably_changed = 1; + } + } if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft != vdec_msg->msgdata.output_frame.framesize.left) - || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top) - || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right) - || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) { - omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left; - omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top; - omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right; - omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom; - DEBUG_PRINT_HIGH("Crop information has changed"); - if (!omx->m_pSwVdec) - { - omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop, - OMX_COMPONENT_GENERATE_PORT_RECONFIG); + || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top) + || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right) + || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) { + if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) || + (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) { + omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom; + omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right; + DEBUG_PRINT_HIGH("Height/Width information has changed. W: %d --> %d, H: %d --> %d", + omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right, + omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom); + } + DEBUG_PRINT_HIGH("Crop information changed. W: %lu --> %d, H: %lu -> %d", + omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right, + omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom); + if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >= + omx->drv_ctx.video_resolution.frame_width) { + vdec_msg->msgdata.output_frame.framesize.left = 0; + if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) { + vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width; } + } + if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >= + omx->drv_ctx.video_resolution.frame_height) { + vdec_msg->msgdata.output_frame.framesize.top = 0; + if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) { + vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height; + } + } + DEBUG_PRINT_LOW("omx_vdec: Adjusted Dim L: %d, T: %d, R: %d, B: %d, W: %d, H: %d", + vdec_msg->msgdata.output_frame.framesize.left, + vdec_msg->msgdata.output_frame.framesize.top, + vdec_msg->msgdata.output_frame.framesize.right, + vdec_msg->msgdata.output_frame.framesize.bottom, + omx->drv_ctx.video_resolution.frame_width, + omx->drv_ctx.video_resolution.frame_height); + omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left; + omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top; + omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right; + omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom; + format_notably_changed = 1; + } + DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d", + vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right, + vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom); + if (format_notably_changed) { + if (omx->is_video_session_supported()) { + omx->post_event (0, vdec_msg->status_code, + OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING); + } else { + if (!omx->client_buffers.update_buffer_req()) { + DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed"); + } + omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop, + OMX_COMPONENT_GENERATE_PORT_RECONFIG); + } } + if (omxhdr->nFilledLen) + omx->prev_n_filled_len = omxhdr->nFilledLen; + output_respbuf = (struct vdec_output_frameinfo *)\ omxhdr->pOutputPortPrivate; output_respbuf->len = vdec_msg->msgdata.output_frame.len; output_respbuf->offset = vdec_msg->msgdata.output_frame.offset; - if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) - { + if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) { output_respbuf->pic_type = PICTURE_TYPE_I; } - if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) - { + if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) { output_respbuf->pic_type = PICTURE_TYPE_P; } if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) { @@ -6923,8 +7146,7 @@ int omx_vdec::async_message_process (void *context, void* message) ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr + (unsigned long)vdec_msg->msgdata.output_frame.offset), vdec_msg->msgdata.output_frame.len); - } - else + } else omxhdr->nFilledLen = 0; if (!omx->m_pSwVdec) { @@ -6962,7 +7184,10 @@ int omx_vdec::async_message_process (void *context, void* message) int ret; fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; ret = ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); - omx->update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height); + omx->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]); omx->drv_ctx.video_resolution.stride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline; omx->drv_ctx.video_resolution.scan_lines = fmt.fmt.pix_mp.plane_fmt[0].reserved[0]; omx->m_port_def.nPortIndex = 1; @@ -7362,7 +7587,6 @@ struct ion_fd_data *fd_data, int flag, int heap_id) ion_buf_info.fd_ion_data = *fd_data; free_ion_memory(&ion_buf_info); fd_data->fd =-1; - close(fd); fd = -ENOMEM; } @@ -7455,6 +7679,10 @@ void omx_vdec::free_input_buffer_header() free (m_inp_mem_ptr); m_inp_mem_ptr = NULL; } + while (m_input_free_q.m_size) { + unsigned address, p2, id; + m_input_free_q.pop_entry(&address, &p2, &id); + } if (drv_ctx.ptr_inputbuffer) { DEBUG_PRINT_LOW("Free Driver Context pointer"); @@ -7555,7 +7783,10 @@ OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop) ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); - update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height); + 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 (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes; DEBUG_PRINT_HIGH("Buffer Size (plane[0].sizeimage) = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage); @@ -7569,6 +7800,11 @@ OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop) else { int extra_idx = 0; + + eRet = is_video_session_supported(); + if (eRet) + return eRet; + buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; buf_size = buffer_prop->buffer_size; extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); @@ -7603,8 +7839,8 @@ OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop) drv_ctx.extradata_info.buffer_size = extra_data_size; buf_size += client_extra_data_size; buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); - DEBUG_PRINT_HIGH("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d) BufType(%d)", - buffer_prop->actualcount, buffer_prop->buffer_size, buf_size, buffer_prop->buffer_type); + DEBUG_PRINT_HIGH("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d) BufType(%d), extradata size %d", + buffer_prop->actualcount, buffer_prop->buffer_size, buf_size, buffer_prop->buffer_type, client_extra_data_size); if (in_reconfig) // BufReq will be set to driver when port is disabled buffer_prop->buffer_size = buf_size; else if (buf_size != buffer_prop->buffer_size) @@ -7645,7 +7881,9 @@ OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop) } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; fmt.fmt.pix_mp.pixelformat = capture_capability; - } else {eRet = OMX_ErrorBadParameter;} + } else { + eRet = OMX_ErrorBadParameter; + } ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); if (ret) @@ -7661,7 +7899,9 @@ OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop) bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - } else {eRet = OMX_ErrorBadParameter;} + } else { + eRet = OMX_ErrorBadParameter; + } if (eRet==OMX_ErrorNone) { ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); @@ -7762,7 +8002,7 @@ OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn) 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; - DEBUG_PRINT_ERROR("update_portdef Width = %lu Height = %lu Stride = %ld" + DEBUG_PRINT_HIGH("update_portdef Width = %lu Height = %lu Stride = %ld" " SliceHeight = %lu", portDefn->format.video.nFrameWidth, portDefn->format.video.nFrameHeight, portDefn->format.video.nStride, @@ -8056,8 +8296,10 @@ void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) } p_extra = (OMX_OTHER_EXTRADATATYPE *) ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3)); + if (!client_extradata) + p_extra = NULL; char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size; - if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen)) + if ((OMX_U8*)p_extra >= (pBuffer + p_buf_hdr->nAllocLen)) p_extra = NULL; OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata; if (data) { @@ -8155,7 +8397,7 @@ OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata, DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only"); return OMX_ErrorIncorrectStateOperation; } - DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d swvdec mode %d", + DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%x] requested[%x] enable[%d], is_internal: %d swvdec mode %d", client_extradata, requested_extradata, enable, is_internal, m_swvdec_mode); if (!is_internal) { @@ -8166,7 +8408,7 @@ OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata, } if (enable) { - if (m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY) { + if (m_pSwVdec == NULL || m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY) { if (requested_extradata & OMX_INTERLACE_EXTRADATA) { control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO; @@ -8313,7 +8555,7 @@ void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, { OMX_STREAMINTERLACEFORMAT *interlace_format; OMX_U32 mbaff = 0; - if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) { + if (!(client_extradata & OMX_INTERLACE_EXTRADATA) || !extra) { return; } extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE; @@ -8359,7 +8601,7 @@ struct vdec_aspectratioinfo *aspect_ratio_info) { OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL; struct msm_vidc_panscan_window *panscan_window; - if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) { + if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA) || !extra) { return; } extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE; @@ -8410,6 +8652,10 @@ struct vdec_aspectratioinfo *aspect_ratio_info) void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra) { + if (!client_extradata || !extra) { + return; + } + OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL; extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE; extra->nVersion.nVersion = OMX_SPEC_VERSION; @@ -8427,7 +8673,7 @@ void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra) void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra) { - if (!client_extradata) { + if (!client_extradata || !extra) { return; } extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE); @@ -8810,8 +9056,7 @@ OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr"); return NULL; } -bool omx_vdec::allocate_color_convert_buf::get_buffer_req -(unsigned int &buffer_size) +bool omx_vdec::allocate_color_convert_buf::get_buffer_req(unsigned int &buffer_size) { bool status = true; pthread_mutex_lock(&omx->c_lock); @@ -8833,42 +9078,43 @@ fail_get_buffer_size: return status; } OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer( - OMX_BUFFERHEADERTYPE *bufhdr) { - unsigned int index = 0; - - if (!enabled) - return omx->free_output_buffer(bufhdr); - if (enabled && omx->is_component_secure()) - return OMX_ErrorNone; - if (!allocated_count || !bufhdr) { - DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr); - return OMX_ErrorBadParameter; - } - index = bufhdr - m_out_mem_ptr_client; - if (index >= omx->drv_ctx.op_buf.actualcount){ - DEBUG_PRINT_ERROR("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]); - } - pmem_fd[index] = -1; + OMX_BUFFERHEADERTYPE *bufhdr) +{ + unsigned int index = 0; + + if (!enabled) + return omx->free_output_buffer(bufhdr); + if (enabled && omx->is_component_secure()) + return OMX_ErrorNone; + if (!allocated_count || !bufhdr) { + DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr); + return OMX_ErrorBadParameter; + } + index = bufhdr - m_out_mem_ptr_client; + if (index >= omx->drv_ctx.op_buf.actualcount){ + DEBUG_PRINT_ERROR("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]); + } + pmem_fd[index] = -1; #ifdef USE_ION - omx->free_ion_memory(&op_buf_ion_info[index]); + omx->free_ion_memory(&op_buf_ion_info[index]); #endif - m_heap_ptr[index].video_heap_ptr = NULL; - if (allocated_count > 0) - allocated_count--; - else - allocated_count = 0; - if (!allocated_count) { - pthread_mutex_lock(&omx->c_lock); - c2d.close(); - init_members(); - pthread_mutex_unlock(&omx->c_lock); - } - return omx->free_output_buffer(&omx->m_out_mem_ptr[index]); + m_heap_ptr[index].video_heap_ptr = NULL; + if (allocated_count > 0) + allocated_count--; + else + allocated_count = 0; + if (!allocated_count) { + pthread_mutex_lock(&omx->c_lock); + c2d.close(); + init_members(); + pthread_mutex_unlock(&omx->c_lock); + } + return omx->free_output_buffer(&omx->m_out_mem_ptr[index]); } OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp, @@ -9014,10 +9260,33 @@ OMX_ERRORTYPE omx_vdec::get_buffer_req_swvdec() } else { - drv_ctx.op_buf.buffer_size = property.uProperty.sOpBuffReq.nSize; + int client_extra_data_size = 0; + if (client_extradata & OMX_FRAMEINFO_EXTRADATA) + { + DEBUG_PRINT_HIGH("Frame info extra data enabled!"); + client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE; + } + if (client_extradata & OMX_INTERLACE_EXTRADATA) + { + DEBUG_PRINT_HIGH("OMX_INTERLACE_EXTRADATA!"); + client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE; + } + if (client_extradata & OMX_PORTDEF_EXTRADATA) + { + client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE; + DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d", + client_extra_data_size); + } + if (client_extra_data_size) + { + client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator + } + drv_ctx.op_buf.buffer_size = property.uProperty.sOpBuffReq.nSize + client_extra_data_size; drv_ctx.op_buf.mincount = property.uProperty.sOpBuffReq.nMinCount; drv_ctx.op_buf.actualcount = property.uProperty.sOpBuffReq.nMinCount; - DEBUG_PRINT_ERROR("swvdec output buf size %d count %d",drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.actualcount); + DEBUG_PRINT_HIGH("swvdec opbuf size %d extradata size %d total size %d count %d", + property.uProperty.sOpBuffReq.nSize, client_extra_data_size, + drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.actualcount); } if (m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY) @@ -9380,29 +9649,6 @@ OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy_dsp( return OMX_ErrorNone; } -static FILE* dsp_output = NULL; - - -int dump_dsp_buffer(OMX_BUFFERHEADERTYPE * buffer) -{ - if (dsp_output==NULL) - { - dsp_output = fopen ("/data/output.dsp", "wb"); - } - if (dsp_output==NULL) - { - return -1; - } - - if (buffer->nFilledLen) - { - fwrite(&buffer->nFilledLen, sizeof(buffer->nFilledLen), 1, dsp_output); - fwrite(buffer->pBuffer, sizeof(uint8), buffer->nFilledLen, dsp_output); - } - return 0; -} - - OMX_ERRORTYPE omx_vdec::fill_buffer_done_dsp(OMX_HANDLETYPE hComp, OMX_BUFFERHEADERTYPE * buffer) { @@ -9458,7 +9704,10 @@ OMX_ERRORTYPE omx_vdec::fill_buffer_done_dsp(OMX_HANDLETYPE hComp, } } - // dump_dsp_buffer(buffer); + if (m_debug.im_buffer_log) + { + log_im_buffer(buffer); + } post_event((unsigned int)&m_cmp, (unsigned int)buffer, OMX_COMPONENT_GENERATE_ETB_SWVDEC); return OMX_ErrorNone; @@ -9645,8 +9894,11 @@ clean_up: { for(i=0; i< drv_ctx.interm_op_buf.actualcount; i++) { - close(drv_ctx.ptr_interm_outputbuffer[i].pmem_fd); - drv_ctx.ptr_interm_outputbuffer[i].pmem_fd = 0; + if(drv_ctx.ptr_interm_outputbuffer) + { + close(drv_ctx.ptr_interm_outputbuffer[i].pmem_fd); + drv_ctx.ptr_interm_outputbuffer[i].pmem_fd = 0; + } free_ion_memory(&drv_ctx.interm_op_buf_ion_info[i]); } } @@ -9792,7 +10044,10 @@ void omx_vdec::swvdec_handle_event(SWVDEC_EVENTHANDLER *pEvent) prop.ePropId = SWVDEC_PROP_ID_DIMENSIONS; SwVdec_GetProperty(m_pSwVdec, &prop); - update_resolution(prop.uProperty.sDimensions.nWidth, prop.uProperty.sDimensions.nHeight); + update_resolution(prop.uProperty.sDimensions.nWidth, + prop.uProperty.sDimensions.nHeight, + prop.uProperty.sDimensions.nWidth, + prop.uProperty.sDimensions.nHeight); drv_ctx.video_resolution.stride = (prop.uProperty.sDimensions.nWidth + 127) & (~127); drv_ctx.video_resolution.scan_lines = (prop.uProperty.sDimensions.nHeight + 31) & (~31); 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 50570674..f0e5a91a 100644 --- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp +++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp @@ -49,9 +49,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <fcntl.h> #include <limits.h> #include <stdlib.h> -#ifdef META_DATA_MODE_SUPPORTED #include <media/hardware/HardwareAPI.h> -#endif #include <media/msm_media_info.h> #ifndef _ANDROID_ @@ -70,7 +68,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "DivXDrmDecrypt.h" #endif //_ANDROID_ -#ifdef META_DATA_MODE_SUPPORTED +#ifdef METADATA_FOR_DYNAMIC_MODE #include "QComOMXMetadata.h" #endif @@ -233,9 +231,7 @@ void* async_message_thread (void *input) DEBUG_PRINT_HIGH("async_message_thread Exited"); break; } - } -#ifdef META_DATA_MODE_SUPPORTED - else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) { + } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) { unsigned int *ptr = (unsigned int *)dqevent.u.data; DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]); omx->buf_ref_remove(ptr[0], ptr[1]); @@ -264,7 +260,6 @@ void* async_message_thread (void *input) break; } } -#endif else { DEBUG_PRINT_HIGH("VIDC Some Event recieved"); continue; @@ -551,6 +546,7 @@ omx_vdec::omx_vdec(): m_error_propogated(false), h264_parser(NULL), client_extradata(0), m_reject_avc_1080p_mp (0), + m_other_extradata(NULL), #ifdef _ANDROID_ m_enable_android_native_buffers(OMX_FALSE), m_use_android_native_buffers(OMX_FALSE), @@ -644,20 +640,16 @@ omx_vdec::omx_vdec(): m_error_propogated(false), #endif m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB; client_buffers.set_vdec_client(this); -#ifdef META_DATA_MODE_SUPPORTED dynamic_buf_mode = false; out_dynamic_list = NULL; -#endif } static const int event_type[] = { V4L2_EVENT_MSM_VIDC_FLUSH_DONE, V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT, V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT, -#ifdef META_DATA_MODE_SUPPORTED V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE, V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER, -#endif V4L2_EVENT_MSM_VIDC_CLOSE_DONE, V4L2_EVENT_MSM_VIDC_SYS_ERROR }; @@ -1443,6 +1435,11 @@ OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) secure_mode = true; arbitrary_bytes = false; role = (OMX_STRING)"OMX.qcom.video.decoder.avc"; + } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure", + OMX_MAX_STRINGNAME_SIZE)){ + secure_mode = true; + arbitrary_bytes = false; + role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2"; } drv_ctx.video_driver_fd = open(device_name, O_RDWR); @@ -1727,7 +1724,7 @@ OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) m_state = OMX_StateLoaded; #ifdef DEFAULT_EXTRADATA - if (eRet == OMX_ErrorNone && !secure_mode) + if (eRet == OMX_ErrorNone) enable_extradata(DEFAULT_EXTRADATA, true, true); #endif eRet=get_buffer_req(&drv_ctx.ip_buf); @@ -3424,7 +3421,6 @@ OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, break; } -#ifdef META_DATA_MODE_SUPPORTED case OMX_QcomIndexParamVideoMetaBufferMode: { StoreMetaDataInBuffersParams *metabuffer = @@ -3462,7 +3458,6 @@ OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, } break; } -#endif case OMX_QcomIndexParamVideoDownScalar: { QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData; struct v4l2_control control; @@ -3842,11 +3837,9 @@ OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage; } #endif -#ifdef META_DATA_MODE_SUPPORTED else if (!strncmp(paramName, "OMX.google.android.index.storeMetaDataInBuffers", sizeof("OMX.google.android.index.storeMetaDataInBuffers") - 1)) { *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode; } -#endif else { DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName); return OMX_ErrorNotImplemented; @@ -3943,6 +3936,13 @@ OMX_ERRORTYPE omx_vdec::allocate_extradata() } } #endif + if (!m_other_extradata) { + m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size); + if (!m_other_extradata) { + DEBUG_PRINT_ERROR("Failed to alloc memory\n"); + return OMX_ErrorInsufficientResources; + } + } return OMX_ErrorNone; } @@ -3956,6 +3956,10 @@ void omx_vdec::free_extradata() } memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); #endif + if (m_other_extradata) { + free(m_other_extradata); + m_other_extradata = NULL; + } } OMX_ERRORTYPE omx_vdec::use_output_buffer( @@ -3997,7 +4001,6 @@ OMX_ERRORTYPE omx_vdec::use_output_buffer( eRet = OMX_ErrorInsufficientResources; } -#ifdef META_DATA_MODE_SUPPORTED if (dynamic_buf_mode) { *bufferHdr = (m_out_mem_ptr + i ); (*bufferHdr)->pBuffer = NULL; @@ -4019,7 +4022,6 @@ OMX_ERRORTYPE omx_vdec::use_output_buffer( (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData); return eRet; } -#endif if (eRet == OMX_ErrorNone) { #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_) if (m_enable_android_native_buffers) { @@ -4153,6 +4155,9 @@ OMX_ERRORTYPE omx_vdec::use_output_buffer( } m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd; + m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len; + m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size; + m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr; *bufferHdr = (m_out_mem_ptr + i ); if (secure_mode) @@ -4913,6 +4918,9 @@ OMX_ERRORTYPE omx_vdec::allocate_output_buffer( drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i; drv_ctx.ptr_outputbuffer[i].bufferaddr = pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i); + m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len; + m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size; + m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr; DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p", pmem_fd, drv_ctx.ptr_outputbuffer[i].offset, @@ -5620,7 +5628,6 @@ if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) { OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_IN OMX_BUFFERHEADERTYPE* buffer) { -#ifdef META_DATA_MODE_SUPPORTED if (dynamic_buf_mode) { private_handle_t *handle = NULL; struct VideoDecoderOutputMetaData *meta; @@ -5655,7 +5662,6 @@ OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, drv_ctx.ptr_outputbuffer[nPortIndex].offset); } -#endif if (m_state == OMX_StateInvalid) { DEBUG_PRINT_ERROR("FTB in Invalid State"); @@ -6334,15 +6340,12 @@ OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp, buffer, buffer->pBuffer); pending_output_buffers --; -#ifdef META_DATA_MODE_SUPPORTED if (dynamic_buf_mode && !secure_mode) { unsigned int nPortIndex = 0; nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr()); munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr, drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size); } -#endif - if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { DEBUG_PRINT_HIGH("Output EOS has been reached"); if (!output_flush_progress) @@ -6621,11 +6624,9 @@ int omx_vdec::async_message_process (void *context, void* message) ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) && (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) { -#ifdef META_DATA_MODE_SUPPORTED if (omx->dynamic_buf_mode && vdec_msg->msgdata.output_frame.len) { vdec_msg->msgdata.output_frame.len = omxhdr->nAllocLen; } -#endif if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) { omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len; omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset; @@ -6655,12 +6656,10 @@ int omx_vdec::async_message_process (void *context, void* message) DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d", omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd); } -#ifdef META_DATA_MODE_SUPPORTED if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) { omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd, omxhdr->nOffset); } -#endif if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) { @@ -7349,7 +7348,7 @@ int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, alloc_data->flags |= ION_SECURE; alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID); - if (secure_mode) + if (secure_mode && (alloc_data->flags & ION_SECURE)) alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID); rc = ioctl(fd,ION_IOC_ALLOC,alloc_data); if (rc || !alloc_data->handle) { @@ -7368,7 +7367,6 @@ int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, ion_buf_info.fd_ion_data = *fd_data; free_ion_memory(&ion_buf_info); fd_data->fd =-1; - close(fd); fd = -ENOMEM; } @@ -7423,12 +7421,10 @@ void omx_vdec::free_output_buffer_header() drv_ctx.op_buf_ion_info = NULL; } #endif -#ifdef META_DATA_MODE_SUPPORTED if (out_dynamic_list) { free(out_dynamic_list); out_dynamic_list = NULL; } -#endif } void omx_vdec::free_input_buffer_header() @@ -7810,12 +7806,10 @@ OMX_ERRORTYPE omx_vdec::allocate_output_headers() drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \ calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount); #endif -#ifdef META_DATA_MODE_SUPPORTED if (dynamic_buf_mode) { out_dynamic_list = (struct dynamic_buf_list *) \ calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount); } -#endif if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer && drv_ctx.ptr_respbuffer) { bufHdr = m_out_mem_ptr; @@ -8037,11 +8031,18 @@ void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) if (!drv_ctx.extradata_info.uaddr) { return; } - p_extra = (OMX_OTHER_EXTRADATATYPE *) + if (!secure_mode) + p_extra = (OMX_OTHER_EXTRADATATYPE *) ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3)); + else + p_extra = m_other_extradata; + char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size; - if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen)) + + if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) { p_extra = NULL; + return; + } OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata; if (data) { while ((consumed_len < drv_ctx.extradata_info.buffer_size) @@ -8068,7 +8069,7 @@ void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) if (m_enable_android_native_buffers) setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, PP_PARAM_INTERLACED, (void*)&enable); - if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) { + if (client_extradata & OMX_INTERLACE_EXTRADATA) { append_interlace_extradata(p_extra, payload->format); p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); } @@ -8969,7 +8970,6 @@ bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE return status; } -#ifdef META_DATA_MODE_SUPPORTED void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset) { int i = 0; @@ -9030,4 +9030,3 @@ void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset) } pthread_mutex_unlock(&m_lock); } -#endif diff --git a/mm-video-v4l2/vidc/vdec/test/omx_vdec_test.cpp b/mm-video-v4l2/vidc/vdec/test/omx_vdec_test.cpp index ee406297..f26cc165 100644 --- a/mm-video-v4l2/vidc/vdec/test/omx_vdec_test.cpp +++ b/mm-video-v4l2/vidc/vdec/test/omx_vdec_test.cpp @@ -856,7 +856,7 @@ void* fbd_thread(void* pArg) #endif if (pBuffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) { OMX_OTHER_EXTRADATATYPE *pExtra; - DEBUG_PRINT(">> BUFFER WITH EXTRA DATA RCVD <<<"); + DEBUG_PRINT_ERROR(">> BUFFER WITH EXTRA DATA RCVD <<<"); pExtra = (OMX_OTHER_EXTRADATATYPE *) ((unsigned)(pBuffer->pBuffer + pBuffer->nOffset + pBuffer->nFilledLen + 3)&(~3)); @@ -877,26 +877,26 @@ void* fbd_thread(void* pArg) case OMX_ExtraDataFrameInfo: { OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)pExtra->data; - DEBUG_PRINT("OMX_ExtraDataFrameInfo: Buf(%p) TSmp(%lld) PicType(%u) IntT(%u) ConMB(%u)", - pBuffer->pBuffer, pBuffer->nTimeStamp, frame_info->ePicType, - frame_info->interlaceType, frame_info->nConcealedMacroblocks); + DEBUG_PRINT_ERROR("OMX_ExtraDataFrameInfo: Buf(%p) TSmp(%lld) PicType(%u) IntT(%u) ConMB(%u)", + pBuffer->pBuffer, pBuffer->nTimeStamp, frame_info->ePicType, + frame_info->interlaceType, frame_info->nConcealedMacroblocks); if (aspectratio_prop) DEBUG_PRINT_ERROR(" FrmRate(%lu), AspRatioX(%lu), AspRatioY(%lu) DispWidth(%lu) DispHeight(%lu)", - frame_info->nFrameRate, frame_info->aspectRatio.aspectRatioX, - frame_info->aspectRatio.aspectRatioY, frame_info->displayAspectRatio.displayHorizontalSize, - frame_info->displayAspectRatio.displayVerticalSize); + frame_info->nFrameRate, frame_info->aspectRatio.aspectRatioX, + frame_info->aspectRatio.aspectRatioY, frame_info->displayAspectRatio.displayHorizontalSize, + frame_info->displayAspectRatio.displayVerticalSize); else - DEBUG_PRINT(" FrmRate(%u), AspRatioX(%u), AspRatioY(%u) DispWidth(%u) DispHeight(%u)", - frame_info->nFrameRate, frame_info->aspectRatio.aspectRatioX, - frame_info->aspectRatio.aspectRatioY, frame_info->displayAspectRatio.displayHorizontalSize, - frame_info->displayAspectRatio.displayVerticalSize); - DEBUG_PRINT("PANSCAN numWindows(%d)", frame_info->panScan.numWindows); - for (unsigned int i = 0; i < frame_info->panScan.numWindows; i++) { - DEBUG_PRINT("WINDOW Lft(%d) Tp(%d) Rgt(%d) Bttm(%d)", - frame_info->panScan.window[i].x, - frame_info->panScan.window[i].y, - frame_info->panScan.window[i].dx, - frame_info->panScan.window[i].dy); + DEBUG_PRINT_ERROR(" FrmRate(%u), AspRatioX(%u), AspRatioY(%u) DispWidth(%u) DispHeight(%u)", + frame_info->nFrameRate, frame_info->aspectRatio.aspectRatioX, + frame_info->aspectRatio.aspectRatioY, frame_info->displayAspectRatio.displayHorizontalSize, + frame_info->displayAspectRatio.displayVerticalSize); + DEBUG_PRINT_ERROR("PANSCAN numWindows(%d)", frame_info->panScan.numWindows); + for (int i = 0; i < frame_info->panScan.numWindows; i++) { + DEBUG_PRINT_ERROR("WINDOW Lft(%d) Tp(%d) Rgt(%d) Bttm(%d)", + frame_info->panScan.window[i].x, + frame_info->panScan.window[i].y, + frame_info->panScan.window[i].dx, + frame_info->panScan.window[i].dy); } break; } @@ -914,17 +914,17 @@ void* fbd_thread(void* pArg) data_ptr++; bytes_cnt++; } - DEBUG_PRINT("OMX_ExtraDataConcealMB: Buf(%p) TSmp(%lld) ConcealMB(%u)", - pBuffer->pBuffer, pBuffer->nTimeStamp, concealMBnum); + DEBUG_PRINT_ERROR("OMX_ExtraDataConcealMB: Buf(%p) TSmp(%lld) ConcealMB(%u)", + pBuffer->pBuffer, pBuffer->nTimeStamp, concealMBnum); } break; case OMX_ExtraDataMP2ExtnData: { - DEBUG_PRINT("\nOMX_ExtraDataMP2ExtnData"); + DEBUG_PRINT_ERROR("\nOMX_ExtraDataMP2ExtnData"); OMX_U8 data = 0, *data_ptr = (OMX_U8 *)pExtra->data; OMX_U32 bytes_cnt = 0; while (bytes_cnt < pExtra->nDataSize) { - DEBUG_PRINT("\n MPEG-2 Extension Data Values[%d] = 0x%x", bytes_cnt, *data_ptr); + DEBUG_PRINT_ERROR("\n MPEG-2 Extension Data Values[%d] = 0x%x", bytes_cnt, *data_ptr); data_ptr++; bytes_cnt++; } @@ -932,11 +932,11 @@ void* fbd_thread(void* pArg) break; case OMX_ExtraDataMP2UserData: { - DEBUG_PRINT("\nOMX_ExtraDataMP2UserData"); + DEBUG_PRINT_ERROR("\nOMX_ExtraDataMP2UserData"); OMX_U8 data = 0, *data_ptr = (OMX_U8 *)pExtra->data; OMX_U32 bytes_cnt = 0; while (bytes_cnt < pExtra->nDataSize) { - DEBUG_PRINT("\n MPEG-2 User Data Values[%d] = 0x%x", bytes_cnt, *data_ptr); + DEBUG_PRINT_ERROR("\n MPEG-2 User Data Values[%d] = 0x%x", bytes_cnt, *data_ptr); data_ptr++; bytes_cnt++; } @@ -1965,32 +1965,30 @@ int Play_Decoder() #endif QOMX_ENABLETYPE extra_data; extra_data.bEnable = OMX_TRUE; -#if 0 - OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamInterlaceExtraData, - (OMX_PTR)&extra_data); -#endif -#if 0 - OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamConcealMBMapExtraData, - (OMX_PTR)&extra_data); -#endif -#if 1 - OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamFrameInfoExtraData, - (OMX_PTR)&extra_data); -#endif -#ifdef TEST_TS_FROM_SEI - OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamH264TimeInfo, + + char frameinfo_value[PROPERTY_VALUE_MAX] = {0}; + char interlace_value[PROPERTY_VALUE_MAX] = {0}; + char h264info_value[PROPERTY_VALUE_MAX] = {0}; + OMX_U32 frameinfo = 0,interlace = 0,h264info =0; + property_get("vidc.vdec.debug.frameinfo", frameinfo_value, "0"); + frameinfo = atoi(frameinfo_value); + if (frameinfo) { + OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamFrameInfoExtraData, (OMX_PTR)&extra_data); -#endif -#if 0 - extra_data.bEnable = OMX_FALSE; - OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamConcealMBMapExtraData, + } + property_get("vidc.vdec.debug.interlace", interlace_value, "0"); + interlace = atoi(interlace_value); + if (interlace) { + OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamInterlaceExtraData, (OMX_PTR)&extra_data); -#endif -#if 0 - extra_data.bEnable = OMX_TRUE; - OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData, + } + property_get("vidc.vdec.debug.h264info", h264info_value, "0"); + h264info = atoi(h264info_value); + if (h264info) { + OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamH264TimeInfo, (OMX_PTR)&extra_data); -#endif + } + /* Query the decoder outport's min buf requirements */ CONFIG_VERSION_SIZE(portFmt); |